如何防止我的剪贴板监视器复制剪贴板数据两次?

How do I prevent my clipboard monitor to copy the clipboard data twice?

我一直在研究一个简单的剪贴板监视器,它可以在剪贴板发生变化时将剪贴板的内容保存在文件文本中。一切正常,但我注意到每当我复制一些东西时,文本会连续复制两次(在图像中,单词数据库就是复制的单词)。

好像这个函数被快速连续调用了两次,我似乎不明白为什么?

public class ClipboardMonitorService extends Service {
private static final String TAG = "ClipboardManager";
private static final String FILENAME = "clipboard-history.txt";

private File mHistoryFile;
private ExecutorService mThreadPool = Executors.newSingleThreadExecutor();

private ClipboardManager mClipboardManager;

@Override
public void onCreate() {
    super.onCreate();


    mHistoryFile = new File(getExternalFilesDir(null),FILENAME);

    mClipboardManager =
            (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
    mClipboardManager.addPrimaryClipChangedListener(mOnPrimaryClipChangedListener);

}



@Override
public void onDestroy() {
    super.onDestroy();

    if (mClipboardManager != null) {
        mClipboardManager.removePrimaryClipChangedListener(
                mOnPrimaryClipChangedListener);
    }
}

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

private boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

private ClipboardManager.OnPrimaryClipChangedListener mOnPrimaryClipChangedListener =
        new ClipboardManager.OnPrimaryClipChangedListener() {
            @Override
            public void onPrimaryClipChanged() {
                Log.d(TAG, "onPrimaryClipChanged");
                ClipData clip = mClipboardManager.getPrimaryClip();

                mThreadPool.execute(new WriteHistoryRunnable(
                        clip.getItemAt(0).getText()));

            }
        };

private class WriteHistoryRunnable implements Runnable {
    private final Date mNow;
    private final CharSequence mTextToWrite;

    public WriteHistoryRunnable(CharSequence text) {
        mNow = new Date(System.currentTimeMillis());
        mTextToWrite = text;
    }

    @Override
    public void run() {
        if (TextUtils.isEmpty(mTextToWrite)) {
            // Don't write empty text to the file
            /*
            TextUtils.isEmpty(string) will return a boolean value so if true nothing is return
            i.e it does nothing
             */
            return;
        }

        if (isExternalStorageWritable()) {
            try {
                Log.i(TAG, "Writing new clip to history:");
                Log.i(TAG, mTextToWrite.toString());
                BufferedWriter writer =
                        new BufferedWriter(new FileWriter(mHistoryFile,true));
                writer.write(String.format("[%s]: ", mNow.toString()));
                writer.write(mTextToWrite.toString());
                writer.newLine();
                writer.close();
            } catch (IOException e) {
                Log.w(TAG, String.format("Failed to open file %s for writing!",
                        mHistoryFile.getAbsoluteFile()));
            }
        } else {
            Log.w(TAG, "External storage is not writable!");
        }
    }
} 
}

看看从哪里复制数据是否重要。即尝试普通的旧 windows 记事本。如果它在那里运行正常,但在其他应用程序中运行不正常,则问题可能出在您从中复制的应用程序上。并非所有应用程序都遵守规则。有时应用程序会多次更新剪贴板,例如每种数据格式一次,而用户只执行了一次操作。
Excel 用于在复制图形时更新剪贴板 24 次以上!