Reputation: 1356
I've been working on a simple clipboard monitor that saves the content of the clipboard on a file text when there is a change in the clipboard. Everything works fine but I noticed that whenever I copy something, the text is copied twice in succession (in the image the word database is the word copied).
It as if the function is called twice in rapid succession and I can't seem to understand why?
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!");
}
}
}
}
Upvotes: 2
Views: 457
Reputation: 15817
See if it matters where you copy the data FROM. i.e. try plain old windows Notepad. If it works ok there, but not from other apps, then the problem may be with the app that you're copying from. Not all apps follow the rules. Sometimes an app will update the clipboard multiple times, such as once for each data format, when the user has only done the action once.
Excel used to update the clipboard 24+ times when you copied a graphic!
Upvotes: 2