Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onPrimaryClipchanged() called multiple times in Android

Tags:

android

I have implemented Background Service to listen to clipboard events system wide..

Service Implementation:

public class ClipService extends Service {
ClipboardManager cm;

@Override
public void onCreate() {
    Log.d("FRAG","onCreate called...");
    super.onCreate();
    cm = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
    cm.addPrimaryClipChangedListener(new ClipboardListener());
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
    cm.removePrimaryClipChangedListener(new ClipboardListener());
}

class ClipboardListener implements ClipboardManager.OnPrimaryClipChangedListener{

     @Override
     public void onPrimaryClipChanged() {
        Log.d("FRAG","onPrimaryClipChanged called..");
        if(cm!=null) {
            String s1 = cm.getPrimaryClip().getItemAt(0).coerceToText(ClipService.this).toString();
            ContentValues cv = new ContentValues();
            cv.put(DatabaseHelper.CONTENT,s1);
            getContentResolver().insert(DataProvider.CONTENT_URI, cv);//Insert using Content provider
        }
     }
}
}

Now my concern is that for every text copied to clipboard three entries are getting inserted for single copy event...i.e. onPrimaryClipChanged is getting called three times..

i am using `Log.d("FRAG","onPrimaryClipChanged called.."); and it is getting logged 3 times so problem seems to be with function being called 3 times for each clipboard change event and not insert part of the code.

What might be the cause of it getting called 3 times?

like image 962
PunitD Avatar asked Feb 12 '15 19:02

PunitD


1 Answers

This is a known issue with WebView/Chrome. I got around it by ignoring the duplicated events within a certain threshold (e.g. 50ms)

ClipboardManager.OnPrimaryClipChangedListener primaryClipChangedListener = new ClipboardManager.OnPrimaryClipChangedListener() {
    private static final long THRESHOLD_MS = 50;
    private long lastChangedTime = 0;
    private String lastString = "";
    @Override
    public void onPrimaryClipChanged() {
        try {
            String str = clipMan.getText().toString();

            // Copying text from certain places will trigger multiple events (e.g. Chrome/WebView generates 3 events)
            // Ignore the duplicated events
            if (System.currentTimeMillis() - lastChangedTime < THRESHOLD_MS && Objects.equals(lastString, str)) {
                return;
            }

            lastChangedTime = System.currentTimeMillis();
            lastString = str;

            // Rest of the logic
            ...
        }
    }
}
like image 179
Chin Avatar answered Nov 14 '22 23:11

Chin