4

In Android, when I copy text from Chrome, Gmail and Inbox my onPrimaryClipChangedlistener method is called 3 times whereas when I copy some text in another app like WhatsApp or Keep this method, as expected, is called just one time.

Example: copying some text in Chrome will result in the following output:

result: null

result: text

result: text

The weird thing is when copying some text from a link or the URL of the page the method is called just one time! So this only happens when I copy text from the "body" of the website.

Is there an elegant and "official" way to solve this? I've read a couple of answers about this topic here, in stackoverflow, but nothing seems to solve my problem.

As I've said this problem only seems to affect certains apps so would this mean is a problem from the other app?

Here my code

ClipboardManager mClipboard;
static boolean bHasClipChangedListener = false;

ClipboardManager.OnPrimaryClipChangedListener mPrimaryChangeListener = new ClipboardManager.OnPrimaryClipChangedListener() {
    public void onPrimaryClipChanged() {
        updateClipData();
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mClipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
    registerPrimaryClipChanged();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterPrimaryClipChanged();
}

void updateClipData() {
    ClipData clip = mClipboard.getPrimaryClip();
    ClipData.Item item = clip.getItemAt(0);
    Log.d(LogUtils.BASIC_LOG, "result: " + item.getText());
}

private void registerPrimaryClipChanged(){
    if(!bHasClipChangedListener){
        mClipboard.addPrimaryClipChangedListener(mPrimaryChangeListener);
        bHasClipChangedListener = true;
    }
}
private void unregisterPrimaryClipChanged(){
    if(bHasClipChangedListener){
        mClipboard.removePrimaryClipChangedListener(mPrimaryChangeListener);
        bHasClipChangedListener = false;
    }
}
Community
  • 1
  • 1
iroyo
  • 723
  • 7
  • 23

1 Answers1

2

Following on from @septemberboy7's commented suggestion

I have done something to work. remove primary clip listener and re add again after 500ms by using Handler.

the following code alleviates the problem:

void startPrimaryClipChangedListenerDelayThread() {
    mClipboardManager.removePrimaryClipChangedListener(mListener);
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
           mClipboardManager.addPrimaryClipChangedListener(mListener);
        }
    }, 500);
}

Call this method immediately in the onPrimaryClipChanged() callback inside the OnPrimaryClipChangedListener to prevent the callback being triggered again for 0.5s. Not ideal but works for now.

Harmeet
  • 35
  • 7