Pourquoi NotificationManagerCompat:: cancelAll() gets SecurityException?
utilisant NotificationManagerCompat
pour annuler toute notification.
NotificationManagerCompat manager =
NotificationManagerCompat.from(ctx.getApplicationContext());
manager.cancelAll();
Il a obtenu l'exception d'un certain temps (la plupart du temps).
sur Andoid 6:
de java.lang.SecurityException: Autorisation de Déni: getCurrentUser() à partir pid=22994, uid=10184 nécessite android.autorisation.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)
sur Android 5.0, 4.4.2:
ava.lang.SecurityException: Autorisation de Déni: getIntentSender() à partir pid=5460, uid=10135, (besoin uid=1000) n'est pas autorisé à envoyer en tant que package android au android.OS.Colis.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)
Questions:
- quelle pourrait en être la cause?
- C'est quoi ces papiers? Est-ce
ctx.getApplicationContext().getApplicationInfo().uid
ouandroid.os.Process.myUid()
?
2 réponses
La réponse ne fournit pas une solution solide pour les le problème, on essaie de donner une explication de la cause à la fois pour l'OP et @66CLSjY , qui a offert le bounty, avec un problème similaire .
inspection de la chaîne de stockage
selon le stacktrace SecurityException
est lancé dans le processus à distance: votre app process" Binder
objet (par exemple INotificationManager.Stub
, ActivityManagerProxy
etc.) fait un Binder
transaction ( mRemote.transact()
) * sur la télécommande Binder
de l'objet et de le lire à partir de l'objet d'une exception ( _reply.readException()
) a eu lieu au sein de l'appel distant(s). Le cas échéant, le message d'exception est analysé et une exception correspondante est lancée dans votre processus.
analyse du message d'exception
les deux messages d'exception (un avec getIntentSender()
et un autre avec getCurrentUser()
) sont assez simples - votre application n'a pas passé un contrôle de permission, ou en d'autres termes, les extraits de code de ActivityManagerService
qui étaient censés être appelés sous le system_server
processus d'identité ( UID=1000
) **, mais, en fait, étaient appelé sous l'identité .
cause Possible et solution de contournement
Il a obtenu l'exception d'un certain temps (la plupart du temps).
sans faire de supposition, ce que vous obtenez "un certain temps" est un comportement inapproprié Android
. enveloppant l'appel de problème avec try/catch
semble être une solution de contournement jusqu'à ce que quelqu'un suggère une solution solide (si elle existe).
* ActivityManagerProxy.setRequestedOrientation () et IAccessibilityManager$Stub$Proxy.sendAccessibilityEvent()
** android.permission.INTERACT_ACROSS_USERS
est de signature | système de niveau de protection
pour moi, il semble qu'il y ait deux possibilités différentes pourquoi cela ne fonctionne pas:
la cause La plus probable est que vous utilisez le mauvais contexte pour faire l'appel; getApplicationContext()
n'est pas fiable à 100% et produit parfois des erreurs étranges, il est toujours préférable d'éviter cet appel. Si vous appelez cancelAll()
d'un Service ou D'une activité, utilisez YourClass.this
au lieu de getApplicationContext()
, s'il s'agit d'un émetteur de radiodiffusion, utilisez la variable de contexte fournie.
Si cela ne fonctionne toujours pas, il peut-être un bug dans NotificationManagerCompat
, essayez si vous pouvez reproduire le même problème avec NotificationManager
. Une solution de rechange pour cela serait de sauvegarder tous vos ID de Notification dans une liste et puis de les annuler chacun avec manager.cancel(id)
. De cette façon, le système ne sera pas essayer d'annuler les Notifications qui n'appartiennent pas à votre application.