OnPrimaryClipChangedListener is called multiple times

On Android, when I copy text from Chrome, Gmail, and Inbox, my onPrimaryClipChangedlistener method is called 3 times, while when copying some text to another application like WhatsApp or Keep this method, it is called only once.

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

result: null

result: text

result: text

the strange thing is to copy some text from the link or URL of the page called by the method only once! So this only happens when I copy text from the body of the website.

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

As I said, this problem only affects certificate applications, so does this mean that it is a problem from another application?

Here is 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;
    }
}
+4
source share
1 answer

The following of @ septemberboy7 commented on a proposal

I did something to work. delete the primary listener clip and add it again after 500 ms using the 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 OnPrimaryClipChangedListener to prevent the callback from being called back for 0.5 seconds. Not perfect, but it works for now.

+2

All Articles