Android SecurityException:<&书信电报;其他套装>&燃气轮机;调用setPrimaryClip时,不允许从uid xxx执行读取剪贴板

Android SecurityException:<&书信电报;其他套装>&燃气轮机;调用setPrimaryClip时,不允许从uid xxx执行读取剪贴板,android,clipboardmanager,android-app-ops,Android,Clipboardmanager,Android App Ops,我收到了关于以下车祸的报告 SecurityException:不允许从uid xxx执行读取\u剪贴板 当用户单击将文本复制到剪贴板的按钮时发生崩溃,如下所示 val clipboard=context.getSystemService(context.clipboard\u服务)作为剪贴板管理器 val clip=ClipData.newPlainText(“标签”,共享URL) 剪贴板.setPrimaryClip(剪辑) 所以我的应用程序不会尝试从剪贴板读取任何内容。真搞不懂为什么会

我收到了关于以下车祸的报告

SecurityException:不允许从uid xxx执行读取\u剪贴板
当用户单击将文本复制到剪贴板的按钮时发生崩溃,如下所示

val clipboard=context.getSystemService(context.clipboard\u服务)作为剪贴板管理器
val clip=ClipData.newPlainText(“标签”,共享URL)
剪贴板.setPrimaryClip(剪辑)
所以我的应用程序不会尝试从剪贴板读取任何内容。真搞不懂为什么会发生这种错误

有人知道这场车祸是怎么发生的吗?我该如何修复

其他信息

这种崩溃只发生在Android 9和Android 10中,并不容易发生(每月20万活跃用户中只有6名用户)

我在Crashlytics中只看到两个(一个是银行应用程序,另一个是音乐应用程序)

我试图阅读
ClipboardService.java
apposmanager.java
的源代码,发现崩溃可能来自
apposmanager
中的
noteOp

以下是崩溃的堆栈跟踪:

Fatal Exception: java.lang.SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD
       at android.os.Parcel.createException(Parcel.java:2087)
       at android.os.Parcel.readException(Parcel.java:2055)
       at android.os.Parcel.readException(Parcel.java:2003)
       at android.content.IClipboard$Stub$Proxy.setPrimaryClip(IClipboard.java:293)
       at android.content.ClipboardManager.setPrimaryClip(ClipboardManager.java:106)
       at my.package.MyClass.copyToClipboard(MyClass.java:63)
       at android.view.View.performClick(View.java:7375)
       at android.view.View.performClickInternal(View.java:7336)
       at android.view.View.access$3900(View.java:822)
       at android.view.View$PerformClick.run(View.java:28214)
       at android.os.Handler.handleCallback(Handler.java:883)
       at android.os.Handler.dispatchMessage(Handler.java:100)
       at android.os.Looper.loop(Looper.java:238)
       at android.app.ActivityThread.main(ActivityThread.java:7829)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:986)

Caused by android.os.RemoteException: Remote stack trace:
    at android.app.AppOpsManager.noteOp(AppOpsManager.java:2568)
    at com.android.server.clipboard.ClipboardService.clipboardAccessAllowed(ClipboardService.java:933)
    at com.android.server.clipboard.ClipboardService.setPrimaryClipInternal(ClipboardService.java:775)
    at com.android.server.clipboard.ClipboardService.setPrimaryClipInternal(ClipboardService.java:710)
    at com.android.server.clipboard.ClipboardService$ClipboardImpl.setPrimaryClip(ClipboardService.java:358)

致命异常:java.lang.SecurityException:来自uid xxx不允许执行读取\u剪贴板
位于android.os.Parcel.createException(Parcel.java:2087)
在android.os.Parcel.readException(Parcel.java:2055)
在android.os.Parcel.readException(Parcel.java:2003)
位于android.content.IClipboard$Stub$Proxy.setPrimaryClip(IClipboard.java:293)
位于android.content.ClipboardManager.setPrimaryClip(ClipboardManager.java:106)
在my.package.MyClass.copyToClipboard(MyClass.java:63)中
在android.view.view.performClick上(view.java:7375)
在android.view.view.performClickInternal(view.java:7336)
在android.view.view.access上$3900(view.java:822)
在android.view.view$PerformClick.run(view.java:28214)
位于android.os.Handler.handleCallback(Handler.java:883)
位于android.os.Handler.dispatchMessage(Handler.java:100)
位于android.os.Looper.loop(Looper.java:238)
位于android.app.ActivityThread.main(ActivityThread.java:7829)
位于java.lang.reflect.Method.invoke(Method.java)
位于com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:986)
由android.os.RemoteException引起:远程堆栈跟踪:
在android.app.apposmanager.noteOp(apposmanager.java:2568)
在com.android.server.ClipboardService.clipboardAccessAllowed(ClipboardService.java:933)上
位于com.android.server.ClipboardService.setPrimaryClipInternal(ClipboardService.java:775)
位于com.android.server.ClipboardService.setPrimaryClipInternal(ClipboardService.java:710)
在com.android.server.ClipboardService.ClipboardService$ClipboardImpl.setPrimaryClip(ClipboardService.java:358)

我终于可以在Android 9中重现崩溃。这就是我发现的

根本原因:当前台应用程序调用
setPrimaryClipboard
时,
ClipboardService
将向
PrimaryClipChangedListener
(如果有)广播事件,并调用
AppOpsManager.noteOp
通知
读取剪贴板
操作

如果不允许侦听器
读取剪贴板
(用户可以使用adb shell命令禁止:
cmd appops set READ\u CLIPBOARD deny
),则
apppsmanager.noteOp
将抛出
安全异常
,并将使前台应用程序崩溃


现在我确信我的代码没有做错任何事情,但不幸的是,我认为我必须把
try/catch
放在
setPrimaryClip

安卓之后禁止阅读剪贴板10@BasilBattikhi我的代码只调用
ClipboardManager.setPrimaryClip
。有没有可能其他应用程序试图读取剪贴板会导致我的应用程序崩溃?@basilbatikhi我现在可以在Android 9上重现这个崩溃。我创建了第一个添加PrimaryClipChangedListener的应用程序,让它在后台运行。然后我使用appops拒绝app1读取剪贴板
cmd appops set READ\u clipboard ignore
。然后我创建了另一个叫做setPrimaryClip的应用程序。它将以相同的错误崩溃。我无法在Android 10中重现此崩溃,因为PrimaryClipChangedListener在后台似乎不起作用。