Android NotificationListenerService lanza DeadObjectException

Tengo una implementación simple de NotificationListenerService para probar la nueva API 4.3. El servicio mismo solía trabajar. Después de eso, agregué el envío de una emisión cuando se agrega una notificación de un paquete particular. Ahora, tan pronto como inicie el servicio, lanza una DeadObjectException . Éste es el seguimiento de la pila:

  E/NotificationService﹕ unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@42c047a0 android.os.DeadObjectException at android.os.BinderProxy.transact(Native Method) at android.service.notification.INotificationListener$Stub$Proxy.onNotificationPosted(INotificationListener.java:102) at com.android.server.NotificationManagerService$NotificationListenerInfo.notifyPostedIfUserMatch(NotificationManagerService.java:241) at com.android.server.NotificationManagerService$2.run(NotificationManagerService.java:814) at android.os.Handler.handleCallback(Handler.java:730) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at com.android.server.ServerThread.run(SystemServer.java:1000) 

Así es como inicie el servicio

 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_start_service: startService(new Intent(this, ConnectService.class)); return true; default: return super.onOptionsItemSelected(item); } } 

Puedo verificar que el servicio comienza, porque hago una onCreate() en él es onCreate() y onDestroy() . Y aquí es cómo se maneja la publicación de notificaciones, si es necesario:

 @Override public void onNotificationPosted(StatusBarNotification sbn) { Log.i(TAG, sbn.getNotification().toString()); if (sbn != null && sbn.getPackageName().equalsIgnoreCase(PKG)) { Intent intent = new Intent(ConnectService.NOTIFY); intent.putExtra("notification", sbn.getNotification().toString()); bManager.sendBroadcast(intent); } } 

La cosa que chupa es que el rastro de la pila es inútil. ¿Qué sucede mal?

2 Solutions collect form web for “Android NotificationListenerService lanza DeadObjectException”

Trate de no iniciar el servicio usted mismo. Si ha habilitado NotificationListenerService en la configuración de seguridad, el sistema debe enlazarla automáticamente.

Como alternativa, compruebe los registros de bloqueo para ver si su servicio se bloqueó o si su proceso se ha anulado. Creo que hay un error en el que si su NotificaitonListerService muere, el sistema no volverá a conectar hasta que reinicie el teléfono o cambie el permiso de notificaciones en la configuración de seguridad.

Me gustaría compartir mi respuesta debido a la información que recogí de diferentes temas en stackoverflow y mis propias pruebas. Si su NotificationListenerService falla (excepción, como IllegalStateException), el sistema lo eliminará y no lo restaurará de nuevo. Usted puede ver que en el logcat:

 592-592/? E/NotificationService﹕ unable to notify listener (posted): android.service.notification.INotificationListener$Stub$Proxy@4291d008 android.os.DeadObjectException .... 

Si el usuario va a Seguridad, Notificaciones, deshabilita y activa la aplicación, todavía no funciona. ¿Por qué? Porque sólo se reiniciará si el usuario reinicia el teléfono o si el usuario vuelve a habilitar la opción, pero ir a través de su aplicación mediante:

 startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); 

Así que tenemos que comprobar dos cosas, primero si la opción está habilitada:

 private boolean checkNotificationSetting() { ContentResolver contentResolver = getContentResolver(); String enabledNotificationListeners = Settings.Secure.getString(contentResolver, "enabled_notification_listeners"); String packageName = getPackageName(); return !(enabledNotificationListeners == null || !enabledNotificationListeners.contains(packageName)); } 

Si está habilitado, verificamos si el servicio es Muerte:

 private boolean isNLServiceCrashed() { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningServiceInfo> runningServiceInfos = manager.getRunningServices(Integer.MAX_VALUE); if (runningServiceInfos != null) { for (ActivityManager.RunningServiceInfo service : runningServiceInfos) { //NotificationListener.class is the name of my class (the one that has to extend from NotificationListenerService) if (NotificationListener.class.getName().equals(service.service.getClassName())) { if (service.crashCount > 0) { // in this situation we know that the notification listener service is not working for the app return true; } return false; } } } return false; } 

¿Qué es este service.crashCount ? La documentación dice:

Número de veces que el proceso del servicio se ha estropeado mientras el servicio está funcionando.

Así que si su más de 0, significa que ya es la muerte. Por lo tanto, en ambos casos, tenemos que advertir al usuario y ofrecer la posibilidad de reiniciar el servicio con la intención que he publicado antes:

 startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); 

Por supuesto, si el servicio se bloquea, será bueno detectar por qué y cuándo prevenirlo también.

  • Razones por las que la intención pasada sería NULL en onStartCommand
  • ¿Cuándo se destruye un servicio iniciado y enlazado?
  • ¿Por qué otro servicio encima de IMarketBillingService?
  • ¿Puede iniciar un IntentService en un proceso separado?
  • Aplicación de Android Service
  • Android Service está creando una y otra vez
  • ¿Cómo mantener un servicio ejecutándose en segundo plano incluso después de que el usuario abandone la aplicación?
  • AVD no se está ejecutando
  • Nombre de la Actividad o Receptor que llama al Servicio
  • Vinculación a un servicio desde otra aplicación
  • El servicio de Android no se reinicia en lollipop
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.