如何在Android Q(10)中以编程方式访问剪贴板数据?

9

众所周知,安卓Q中谷歌已经停止了通过剪切板管理器在后台读取数据的功能,因此我需要在用户返回到活动时,无需用户进行粘贴操作和不需要粘贴按钮,就能够直接将数据复制到编辑框中。

但问题是,使用getPrimaryClip()尝试读取数据会返回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>

2个回答

26
你应该在 Window.Callback.onWindowFocusChanged(true) 中访问剪贴板,因为那是你获得输入焦点的时刻,在Android 10(Q)中需要输入焦点才能读取剪贴板。在onResume中你不一定拥有输入焦点。

Android 11怎么样?您能否也回答一下关于Android 11的问题? - s4suryapal
@s4suryapal 这应该能在 Android 10 及以上版本上运行,包括 Android 11。 - Ryan M

2
接受的答案是正确的,但这是它的扩展版本。这将获取剪贴板中最后复制的项目。
@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);
}

就这些。

剪贴板的常见用法:

上述方法会在应用程序处于焦点状态时持续获取剪贴板数据,因此最好添加一个布尔值来检查一次剪贴板数据。但是,如果您正在尝试在用户暂停然后恢复活动时(例如从其他应用程序复制文本,然后返回到您的应用程序),显示对话框,则最好添加一个布尔值以检查是否应该显示对话框,如下所示:

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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接