9

As we know read data by Clipboard Manager in the background was stopped by Google in android Q, so I need anyway to paste data copied directly in edit text when a user returns to activity without user make a paste and without paste button.

The issue is that trying to read the data with getPrimaryClip() returns null.

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_copy_and_paste);

           ed_editText = findViewById(R.id.ed_editText);

    }
    @Override
    protected void onResume() {
        super.onResume();
           getCopy()
        }

    private void getCopy() {
        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
                if (clipboard != null && clipboard.hasPrimaryClip() && clipboard.getPrimaryClip() != null) {
                    CharSequence clip = clipboard.getPrimaryClip().getItemAt(0).coerceToText(CopyAndPasteActivity.this).toString();
                        ed_editText.setText(clip.toString());
                }      

    }

XML

      <EditText
                        android:id="@+id/ed_editText"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_marginLeft="24dp"
                        android:layout_marginStart="24dp"
                        android:maxLines="1"
                        android:lines="1"
                        android:focusable="true"
                        android:textSize="14sp"
                        android:inputType="text"
                        android:focusableInTouchMode="true"
                        android:layout_weight="1"
                        android:background="@null" >
                    <requestFocus />
                    </EditText>

Cœur
  • 37,241
  • 25
  • 195
  • 267
user3661581
  • 539
  • 1
  • 7
  • 17

2 Answers2

25

You should access the clipboard in Window.Callback.onWindowFocusChanged(true), as that is the moment at which you gain input focus, which is required to read the clipboard in Android 10 (Q). You don't yet necessarily have input focus in onResume.

Ryan M
  • 18,333
  • 31
  • 67
  • 74
2

The accepted answer is correct, but this is an extended version of it.

This will get the last copied item from the clipboard.

@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        boolean isAndroid10Plus = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q);

        if(!isAndroid10Plus) return;

        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0);
        String data = item.getText().toString();
        super.onWindowFocusChanged(hasFocus);
}

That's it.

Common use of clipboard:

The way above will continuously get the clipboard data as long as the app is on focus, so you better add a boolean to check for clipboard data once. But if you're trying to show a dialog whenever the user pauses then resumes the activity (maybe copies a text from another app then goes back to your app), then better to add a boolean to check if you should show a dialog or not like this:

private boolean shouldCheckClipboard = true; // default should be true

@Override
    protected void onStop() {
        shouldCheckClipboard = true; // user has left the app, we should get the clipboard data when they're back
        super.onStop();
}

private void showDialog(String data){
shouldCheckClipboard = false; // stop asking for clipboard data
// handle data to show a dialog
}

@Override
    public void onWindowFocusChanged(boolean hasFocus) {
        boolean isAndroid10Plus = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q);

        if(!(isAndroid10Plus || shouldCheckClipboard) return;

        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); // get position 0 of the clipboard (last copied item)
        String data = item.getText().toString();
        showDialog(data); // pass clipboard data then show dialog
        super.onWindowFocusChanged(hasFocus);
}
Regex
  • 528
  • 4
  • 20