当我将文本复制到剪贴板上时,onPrimaryClipChanged方法被调用两次。有什么想法吗?
@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;
}
测试用例: 从BBC网站复制文本“继续”将产生以下输出:
继续
继续
但是如果我调试程序,我可以看到clipData对象具有值:
ClipData {text / plain {T:continue}}
第一次调用onPrimaryClipChanged()并
ClipData {text / plain“BBC - 主页”{T:continue}}
下次调用onPrimaryClipChanged()时。
所以基本上第一次ClipDescription是{text / plain},第二次是ClipDescription {text / plain“BBC - Homepage”}(即包括网页标题)
答案 0 :(得分:8)
我假设你没有注册多个监听器,我不能说它是bug,你仍然可以解决它。尝试这样的事情:
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();
}
}
});
答案 1 :(得分:5)
我也遇到了这个问题,最后我知道为什么会多次拨打!!!
通常我们addPrimaryClipChangedListener()
,但我们没有removePrimaryClipChangedListener()
。
请参阅: http://developer.android.com/reference/android/content/Context.html#CLIPBOARD_SERVICE
与getSystemService(String)一起使用以检索ClipboardManager以访问和修改全局剪贴板的内容。
这意味着我们应该removePrimaryClipChangedListener()
手动!
我的解决方案代码:
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();
}
答案 2 :(得分:1)
这是我的防范方法,以防止每个副本调用两次ClipboardManager OnPrimaryClipChangedListener。
long lastCopiedTime = 0;
ClipboardManager.OnPrimaryClipChangedListener onPrimaryClipChangedListener = new ClipboardManager.OnPrimaryClipChangedListener() {
@Override
public void onPrimaryClipChanged() {
ClipboardManager clipBoard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
String pasteData = "";
ClipData.Item item = clipBoard.getPrimaryClip().getItemAt(0);
if (System.currentTimeMillis() - lastCopiedTime > TimeUnit.SECONDS.toMillis(1)) {
if (StringUtils.isNotBlank(item.getText())) {
String s = item.getText().toString();
if (StringUtils.isNotBlank(s)) {
pasteData = s.trim();
if (StringUtils.isNotBlank(pasteData)) {
/// do something here
}
}
}
}
lastCopiedTime = System.currentTimeMillis();
}
}
}
};
答案 3 :(得分:0)
//预防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
}
}