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

Android 为什么NotificationManagerCompat::cancelAll()获取SecurityException?,android,android-notifications,android-securityexception,android-binder,Android,Android Notifications,Android Securityexception,Android Binder,使用通知管理器compat取消所有通知 NotificationManagerCompat manager = NotificationManagerCompat.from(ctx.getApplicationContext()); manager.cancelAll(); 有一段时间它出现了异常(大多数时间都有效) 关于Andoid 6: java.lang.SecurityException:权限拒绝:pid=22994、uid=10184中的getCurrentUser()需

使用
通知管理器compat
取消所有通知

NotificationManagerCompat manager =  
    NotificationManagerCompat.from(ctx.getApplicationContext());
manager.cancelAll();
有一段时间它出现了异常(大多数时间都有效)

关于Andoid 6:

java.lang.SecurityException:权限拒绝:pid=22994、uid=10184中的getCurrentUser()需要跨用户的android.Permission.INTERACT

在Android 5.0、4.4.2上:

ava.lang.SecurityException:权限拒绝:pid=5460,uid=10135,(需要uid=1000)中的getIntentSender()不允许作为包发送 位于android.os.Parcel.readException(Parcel.java:1465)

问题:

  • 原因可能是什么
  • 这些证件是什么?它是
    ctx.getApplicationContext().getApplicationInfo().uid
    还是
    android.os.Process.myUid()

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

    最可能的原因是您使用了错误的上下文来拨打电话
    getApplicationContext()
    不是100%可靠的,有时会产生奇怪的错误,因此最好避免此调用。如果您是从服务或活动调用
    cancelAll()
    ,请使用
    YourClass。此
    而不是
    getApplicationContext()
    ,如果它是从BroadcastReceiver调用的,请使用提供的上下文变量

    如果这仍然不起作用,则可能是
    NotificationManager Compat
    中的错误,请尝试使用
    NotificationManager
    重现相同的问题。解决方法是将所有通知id保存在一个列表中,然后使用
    manager.cancel(id)
    取消它们。这样,系统就不会试图取消任何不属于你的应用程序的通知。

    答案并没有为问题提供一个可靠的解决方案,而是试图解释OP和提供奖金的人的原因


    检查堆栈跟踪

    根据stacktrace,在远程进程中抛出
    SecurityException
    :在远程
    Binder
    对象(例如
    INotificationManager.Stub
    ActivityManagerProxy
    等)(
    mRemote.transact()
    )上,从对象读取异常(
    \u reply.readException()
    )在远程调用中发生。如果有,则在您的过程中

    分析异常消息

    异常消息(一条带,另一条带)都非常简单-您的应用程序没有通过权限检查,或者换句话说,
    ActivityManagerService
    的代码片段本来应该被调用(
    UID=1000
    )**,但实际上被调用了

    可能的原因和解决方法

    有一段时间它出现了异常(大多数时间都有效)

    如果不做假设,你在“某个时候”得到的是不合适的
    Android
    行为。在有人提出可靠的解决方案(如果存在)之前,这似乎是一个解决办法


    *和

    **
    android.permission.interaction\u跨用户
    属于

    “是ctx.getApplicationContext().getApplicationInfo().uid还是android.os.Process.myUid()?”--对于大多数Android应用程序,这些应该是相同的。不过,您的两个错误都很奇怪。感谢Commonware!奇怪的是,它只是使用应用程序的上下文来删除所有通知(从同一应用程序内部发布),但会出现安全异常。可能的原因是什么?所以我想我得试着抓住这个癌症。@66CLSjY我想,根据这些
    pid
    uid
    是否属于你的应用程序,这可能是“绑定器同步”中的一个错误,比如说,
    getIntentSender()
    在使用系统的ID(
    uid
    =1000)调用时,使用
    uid
    绑定器的
    标识调用,或者在处理您的调用时,使用原始调用方(您的)调用其他对象的绑定器标识而不首先清除它。我想您对此无能为力,只能捕获问题调用引发的异常。@Onik,这确实说明了这个问题是如何产生的。谢谢。
    
    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)
    
    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)