为什么NotificationManagerCompat :: cancelAll()获取SecurityException?

时间:2016-04-14 21:06:33

标签: android android-notifications android-securityexception android-binder

使用NotificationManagerCompat取消所有通知。

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

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

on Andoid 6:

  

java.lang.SecurityException:Permission Denial:来自pid = 22994的getCurrentUser(),uid = 10184需要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:权限拒绝:来自pid = 5460的getIntentSender(),uid = 10135,(需要uid = 1000)不允许发送包作为android          在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. 这里有什么身份证?是ctx.getApplicationContext().getApplicationInfo().uid还是android.os.Process.myUid()

2 个答案:

答案 0 :(得分:4)

答案没有为问题提供可靠的解决方案,而是试图解释OP和@66CLSjY的原因,谁提供了赏金,similar issue

检查堆栈跟踪

根据堆栈跟踪SecurityException在远程进程中抛出:您的应用进程'远程Binder对象上的INotificationManager.Stub对象(例如ActivityManagerProxymRemote.transact()等)makes a Binder transactionBinder)*并从对象中读取异常(_reply.readException())发生在远程调用中。如果有的话,您流程中的exception message is analyzed and a corresponding exception is thrown

分析异常消息

异常消息(一个getIntentSender()和另一个getCurrentUser())非常简单 - 您的应用没有通过权限检查,换句话说,代码片段应该被称为under the system_server process' identityActivityManagerService)**的UID=1000,但实际上被称为under your app process' identity

可能的原因和解决方法

  

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

如果没有做出假设,那么"某些时间" 是不正当的Android行为。 Wrapping the problem call with try/catch似乎是一种解决方法,直到有人建议一个可靠的解决方案(如果存在)。

* ActivityManagerProxy.setRequestedOrientation()IAccessibilityManager$Stub$Proxy.sendAccessibilityEvent()
** android.permission.INTERACT_ACROSS_USERS属于signature | system protection level

答案 1 :(得分:0)

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

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

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