android android-notifications android-securityexception android-binder

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:

  1. ¿Qué podría ser la causa?
  2. ¿Qué son esos id aquí? ¿Es ctx.getApplicationContext().getApplicationInfo().uid o android.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