SecurityException: <<other_package>> 来自 uid xxx 不允许在调用 setPrimaryClip 时执行 READ_CLIPBOARD
SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD when calling setPrimaryClip
我收到了以下崩溃的报告
SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD
当用户单击将文本复制到剪贴板的按钮时发生崩溃,如下所示。
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("label", shareUrl)
clipboard.setPrimaryClip(clip)
所以我的应用程序不会尝试从剪贴板读取任何内容。真的很困惑为什么会发生这个错误。
有谁知道这个崩溃是怎么发生的,我该如何解决?
附加信息
此崩溃只发生在 Android 9 和 Android 10 并且不容易发生(每月 20 万活跃用户中只有 6 名用户)
我在 Crashlytics 中只看到两个 <>(一个是银行应用程序,另一个是音乐应用程序)。
我尝试阅读ClipboardService.java
和AppOpsManager.java
的源代码,发现崩溃可能来自AppOpsManager
中的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.access00(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)
我终于可以重现 Android 9 中的崩溃了。这就是我发现的...
根本原因: 当前台应用程序调用 setPrimaryClipboard
时,ClipboardService
会将事件广播到 PrimaryClipChangedListener
(如果有)并将还可以致电 AppOpsManager.noteOp
以通知 READ_CLIPBOARD
操作。
如果侦听器不允许 READ_CLIPBOARD
(用户可以使用 adb shell 命令禁止:cmd appops set <package> READ_CLIPBOARD deny
),AppOpsManager.noteOp
将抛出一个 SecurityException
并且会使前台应用程序崩溃。
现在我确定我的代码没有做错任何事,但不幸的是我想我必须把 try/catch
放在 setPrimaryClip
周围
我收到了以下崩溃的报告
SecurityException: <<other_package>> from uid xxx not allowed to perform READ_CLIPBOARD
当用户单击将文本复制到剪贴板的按钮时发生崩溃,如下所示。
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText("label", shareUrl)
clipboard.setPrimaryClip(clip)
所以我的应用程序不会尝试从剪贴板读取任何内容。真的很困惑为什么会发生这个错误。
有谁知道这个崩溃是怎么发生的,我该如何解决?
附加信息
此崩溃只发生在 Android 9 和 Android 10 并且不容易发生(每月 20 万活跃用户中只有 6 名用户)
我在 Crashlytics 中只看到两个 <
我尝试阅读ClipboardService.java
和AppOpsManager.java
的源代码,发现崩溃可能来自AppOpsManager
中的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.access00(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)
我终于可以重现 Android 9 中的崩溃了。这就是我发现的...
根本原因: 当前台应用程序调用 setPrimaryClipboard
时,ClipboardService
会将事件广播到 PrimaryClipChangedListener
(如果有)并将还可以致电 AppOpsManager.noteOp
以通知 READ_CLIPBOARD
操作。
如果侦听器不允许 READ_CLIPBOARD
(用户可以使用 adb shell 命令禁止:cmd appops set <package> READ_CLIPBOARD deny
),AppOpsManager.noteOp
将抛出一个 SecurityException
并且会使前台应用程序崩溃。
现在我确定我的代码没有做错任何事,但不幸的是我想我必须把 try/catch
放在 setPrimaryClip