ClipboardManager OnPrimaryClipChangedListener is called twice for every copy

匿名 (未验证) 提交于 2019-12-03 01:10:02

问题:

When I copy text to the clipboard onPrimaryClipChanged method is called twice. Any ideas why?

@Override public boolean onCreateOptionsMenu(Menu menu) {     getMenuInflater().inflate(R.menu.main, menu);     final ClipboardManager cliboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);      cliboardManager             .addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() {                  @Override                 public void onPrimaryClipChanged() {                     ClipData clipData = cliboardManager.getPrimaryClip();                     System.out                             .println("********** clip changed, clipData: "                                     + clipData.getItemAt(0));                 }             });     return true; }

Test case: Copying the text "continue" from the BBC web site will result in the following output:

continue

continue

But if I debug the program I can see that the clipData object has value:

ClipData { text/plain {T:continue } }

the first time onPrimaryClipChanged() is called and

ClipData { text/plain "BBC - Homepage" {T:continue } }

the next time onPrimaryClipChanged() is called.

So basically the first time ClipDescription is { text/plain } and the second time is ClipDescription { text/plain "BBC - Homepage" } (i.e including the title of the web page)

回答1:

I assume you didn't register multiple listeners, I can't say it is bug, you still you can workaround it. Try something like this:

   String mPreviousText = "";     cliboardManager                 .addPrimaryClipChangedListener(new OnPrimaryClipChangedListener() {                      @Override                     public void onPrimaryClipChanged() {                         ClipData clipData = cliboardManager.getPrimaryClip();                         System.out                                 .println("********** clip changed, clipData: "                                         + clipData.getItemAt(0));                          ClipData.Item item = clipData.getItemAt(0);                          if(mPreviousText.equals(item.getText().toString())) return;                          else{                             /// do something                             mPrevousText = item.getText().toString();                          }                     }                 });


回答2:

I meet this problem too, finally I know why it will call multi times!!!

Usually we addPrimaryClipChangedListener(), but we don't removePrimaryClipChangedListener().

See: http://developer.android.com/reference/android/content/Context.html#CLIPBOARD_SERVICE

Use with getSystemService(String) to retrieve a ClipboardManager for accessing and modifying the contents of the global clipboard.

It means we should removePrimaryClipChangedListener() manually!

My solution code :

ClipboardManager myClipBoard ; static boolean bHasClipChangedListener = false;  ClipboardManager.OnPrimaryClipChangedListener mPrimaryClipChangedListener = new ClipboardManager.OnPrimaryClipChangedListener() {     public void onPrimaryClipChanged() {         ClipData clipData = myClipBoard.getPrimaryClip();         Log.d("henrytest", "********** clip changed, clipData: " + clipData.getItemAt(0));     } };  private void RegPrimaryClipChanged(){     if(!bHasClipChangedListener){         myClipBoard.addPrimaryClipChangedListener(mPrimaryClipChangedListener);         bHasClipChangedListener = true;     } } private void UnRegPrimaryClipChanged(){     if(bHasClipChangedListener){         myClipBoard.removePrimaryClipChangedListener(mPrimaryClipChangedListener);         bHasClipChangedListener = false;     } }  @Override protected void onCreate(Bundle savedInstanceState) {     myClipBoard = (ClipboardManager) Clipboard.this.getSystemService(android.content.Context.CLIPBOARD_SERVICE); }  @Override protected void onResume() {     super.onResume();     RegPrimaryClipChanged(); }  @Override protected void onPause() {     super.onPause();     UnRegPrimaryClipChanged(); }  @Override protected void onStop() {     super.onStop();     //UnRegPrimaryClipChanged(); }  @Override protected void onDestroy() {     super.onDestroy();     //UnRegPrimaryClipChanged(); }


回答3:

// Prevention duplicate action of OnPrimaryClipChangedListener.

private ExecutorService mThreadPool = Executors.newSingleThreadExecutor(); static boolean isExpireData = true;  class hasExpireData implements Runnable {      @Override     public void run() {         // TODO Auto-generated method stub          isExpireData = true;     }  }  private ClipboardManager.OnPrimaryClipChangedListener mOnPrimaryClipChangedListener =         new ClipboardManager.OnPrimaryClipChangedListener() {     @Override     public void onPrimaryClipChanged() {         Log.d(TAG, "onPrimaryClipChanged");         ClipData clip = mClipboardManager.getPrimaryClip();          Thread expireData = new Thread(new hasExpireData());         new Handler().postDelayed(expireData, 500); // 0.5 seconds wait...          if(isExpireData) {             isExpireData = false;             mThreadPool.execute(new TextRunnable(                     clip.getItemAt(0).getText()));         }      } };  private class TextRunnable implements Runnable {     public TextRunnable(CharSequence text) {         // text store to this class     }      @Override     public void run() {         // text other process     } }


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!