28

用于NotificationManagerCompat取消所有通知。

NotificationManagerCompat manager =  
    NotificationManagerCompat.from(ctx.getApplicationContext());
manager.cancelAll();

它有一段时间出现异常(大部分时间都有效)。

在安卓 6 上:

java.lang.SecurityException: Permission Denial: getCurrentUser() from pid=22994, uid=10184 requires android.permission.INTERACT_ACROSS_USERS

Fatal Exception: java.lang.SecurityException: Permission Denial: getCurrentUser() from pid=22994, uid=10184 requires android.permission.INTERACT_ACROSS_USERS
   at android.os.Parcel.readException(Parcel.java:1602)
   at android.os.Parcel.readException(Parcel.java:1555)
   at android.app.INotificationManager$Stub$Proxy.cancelAllNotifications(INotificationManager.java:649)
   at android.app.NotificationManager.cancelAll(NotificationManager.java:323)
   at android.support.v4.app.NotificationManagerCompat.cancelAll(NotificationManagerCompat.java:197)

在 Android 5.0、4.4.2 上:

ava.lang.SecurityException: Permission Denial: getIntentSender() from pid=5460, uid=10135, (need uid=1000) is not allowed to send as package android at android.os.Parcel.readException(Parcel.java:1465)

Fatal Exception: java.lang.SecurityException: Permission Denial: getIntentSender() from pid=3109, uid=10153, (need uid=1000) is not allowed to send as package android
   at android.os.Parcel.readException(Parcel.java:1472)
   at android.os.Parcel.readException(Parcel.java:1426)
   at android.app.INotificationManager$Stub$Proxy.cancelAllNotifications(INotificationManager.java:271)
   at android.app.NotificationManager.cancelAll(NotificationManager.java:220)
   at android.support.v4.app.NotificationManagerCompat.cancelAll(NotificationManagerCompat.java:197)

问题:

  1. 可能是什么原因?
  2. 这里的那些 id 是什么?是ctx.getApplicationContext().getApplicationInfo().uid还是android.os.Process.myUid()
4

2 回答 2

6

答案并没有为该问题提供可靠的解决方案,而是试图为提供赏金的 OP 和@66CLSjY提供类似问题的原因的解释。


检查堆栈跟踪

根据SecurityException远程进程中抛出的堆栈跟踪:您的应用程序进程的Binder对象(例如INotificationManager.StubActivityManagerProxy)在远程对象上进行Binder事务mRemote.transact())*Binder并从对象中读取_reply.readException()远程调用中发生的异常()。如果有,则会分析异常消息并在您的进程中引发相应的异常。

分析异常消息

两个异常消息(一个带有getIntentSender(),另一个带有getCurrentUser())都非常简单 - 您的应用程序没有通过权限检查,或者换句话说,ActivityManagerService应该system_server进程的身份下调用的代码片段( UID=1000) ** ,但实际上是在您的应用程序进程的身份下调用的。

可能的原因和解决方法

它有一段时间出现异常(大部分时间都有效)。

在不做任何假设的情况下,你得到的“一段时间”是不正当的Android行为。在有人提出可靠的解决方案(如果存在)之前,将问题调用包装起来try/catch似乎是一种解决方法。


* ActivityManagerProxy.setRequestedOrientation()IAccessibilityManager$Stub$Proxy.sendAccessibilityEvent()
**android.permission.INTERACT_ACROSS_USERS签名 | 系统保护等级

于 2016-11-10T23:18:28.623 回答
0

对我来说,这听起来有两种不同的可能性为什么这不起作用:

最可能的原因是您使用错误的上下文进行调用;getApplicationContext()不是 100% 可靠的,有时会产生奇怪的错误,最好避免这个调用。如果您cancelAll()从 Service 或 Activity 调用,请使用YourClass.this而不是getApplicationContext(),如果它来自 BroadcastReceiver,请使用提供的 Context 变量。

如果这仍然不起作用,则可能是 中的错误NotificationManagerCompat,请尝试使用NotificationManager. 一种解决方法是将所有通知 ID 保存在一个列表中,然后使用manager.cancel(id). 这样系统就不会尝试取消任何不属于您的应用的通知。

于 2016-11-10T09:58:19.447 回答