android - ¿Por qué NotificationManagerCompat:: cancelAll() obtiene SecurityException?
android-notifications android-securityexception (2)
A mí me parece que hay dos posibilidades diferentes por las que esto no funciona:
La causa más probable es que esté utilizando el contexto incorrecto para realizar la llamada; getApplicationContext()
no es 100% confiable y algunas veces produce errores extraños, siempre es mejor evitar esta llamada. Si está llamando a cancelAll()
desde un Servicio o Actividad, use YourClass.this
lugar de getApplicationContext()
, si es de un BroadcastReceiver, use la variable Context provista.
Si esto todavía no funciona, podría ser un error en NotificationManagerCompat
, intente si puede reproducir el mismo problema con NotificationManager
. Una solución alternativa sería guardar todas sus ID de notificación en una lista y luego cancelarlas con manager.cancel(id)
. De esa manera, el sistema no intentará cancelar ninguna Notificación que no pertenezca a su aplicación.
Usando NotificationManagerCompat
para cancelar todas las notificaciones.
NotificationManagerCompat manager =
NotificationManagerCompat.from(ctx.getApplicationContext());
manager.cancelAll();
Se hizo una excepción algún tiempo (la mayoría funciona a tiempo).
en Andoid 6:
java.lang.SecurityException: Denegación de permiso: getCurrentUser () de pid = 22994, uid = 10184 requiere 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)
en Android 5.0, 4.4.2:
ava.lang.SecurityException: Denegación de permiso: getIntentSender () de pid = 5460, uid = 10135, (need uid = 1000) no está permitido enviar como paquete android en 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)
Preguntas:
- ¿Qué podría ser la causa?
- ¿Qué son esos id aquí? ¿Es
ctx.getApplicationContext().getApplicationInfo().uid
oandroid.os.Process.myUid()
?
La respuesta no proporciona una solución sólida para el problema, sino que intenta dar una explicación de la causa tanto para el OP como para 66CLSjY , que ofreció la recompensa, con un problema similar .
Inspeccionando el apilamiento
De acuerdo con el stacktrace, SecurityException
se lanza en el proceso remoto: el objeto Binder
proceso de su aplicación (por ejemplo, INotificationManager.Stub
, ActivityManagerProxy
, etc.) realiza una transacción Binder
( mRemote.transact()
) * en el objeto Binder
remoto y se lee del objeto se produjo una excepción ( _reply.readException()
) dentro de la (s) llamada (s) remota (s). Si hay alguno, se analiza el mensaje de excepción y se lanza una excepción correspondiente en su proceso.
Analizando el mensaje de excepción.
Tanto los mensajes de excepción (uno con getIntentSender()
como otro con getCurrentUser()
) son bastante sencillos: su aplicación no pasó una verificación de permisos, o en otras palabras, los fragmentos de código de ActivityManagerService
que debían llamarse bajo el Identidad del proceso system_server
( UID=1000
) **, pero, de hecho, fueron llamados bajo la identidad del proceso de su aplicación .
Posible causa y solución
Se hizo una excepción algún tiempo (la mayoría funciona a tiempo).
Sin hacer una suposición, lo que se obtiene "algún tiempo" es un comportamiento incorrecto de Android
. Ajustar la llamada del problema con try/catch
parece ser una solución hasta que alguien sugiere una solución sólida (si existe).
* ActivityManagerProxy.setRequestedOrientation() y IAccessibilityManager$Stub$Proxy.sendAccessibilityEvent()
** android.permission.INTERACT_ACROSS_USERS
es de firma | nivel de protección del sistema