I have been experiencing some weird behavior. My app randomly fails to detect/pick up clipboard content (other apps do detect and paste it correctly). I am following these guidelines.
My code looks like this.
public class ClipboardProvider {
private final ClipboardManager clipboard;
@Inject
public ClipboardProvider(Context context) {
clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
}
/**
* Copy some text to the clipboard.
*
* @param label User-visible label for the pasted data.
* @param text The actual text to copy.
*/
public void copy(String label, String text) {
final ClipData clip = ClipData.newPlainText(label, text);
clipboard.setPrimaryClip(clip);
}
/**
* Grab some text from the clipboard.
*/
public Optional<String> paste() {
if (!clipboard.hasPrimaryClip()) {
return Optional.empty();
}
final ClipData primaryClip = clipboard.getPrimaryClip();
if (primaryClip.getItemCount() == 0) {
return Optional.empty();
}
final ClipData.Item item = primaryClip.getItemAt(0);
if (item == null) {
return Optional.empty();
}
final CharSequence text = item.getText();
if (text == null) {
return Optional.empty();
}
return Optional.of(text.toString());
}
/**
* Create an Observable that reports changes on the system clipboard (fires immediately upon
* subscribe).
*/
public Observable<String> watchPrimaryClip() {
return Observable.using(
ClipboardListener::new,
clipboardListener -> Observable.create((Observable.OnSubscribe<String>)
(subscriber) -> {
clipboardListener.setSubscriber(subscriber);
clipboardListener.onPrimaryClipChanged();
clipboard.addPrimaryClipChangedListener(clipboardListener);
}
),
clipboard::removePrimaryClipChangedListener
).distinctUntilChanged();
}
private class ClipboardListener implements ClipboardManager.OnPrimaryClipChangedListener {
Subscriber<? super String> subscriber;
public void setSubscriber(Subscriber<? super String> subscriber) {
this.subscriber = subscriber;
}
@Override
public void onPrimaryClipChanged() {
if (subscriber != null && !subscriber.isUnsubscribed()) {
subscriber.onNext(paste().orElse(""));
}
}
}
}
I am using android.content.ClipboardManager
and using a targetSdk = 28
and ClipboardProvider
is injected using Dagger
. It's being injected an applicationContext
.
In particular, what I'm seeing is that watchPrimaryClip()
emits events with null
because inside paste()
, clipboard.hasPrimaryClip()
returns false
.
Anyone experiencing something similar? Couldn't find nothing resembling this. Any ideas?