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?

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.

  • Cómo cancelar un servicio de primer plano de usar la notificación (borrar descartar) o borrar todas las notificaciones?
  • El servicio de primer plano se asesina al realizar operaciones relacionadas con Internet
  • Enviar datos de la actividad al servicio
  • Android verificar el estado WIFI (desconectado o el usuario ha cambiado WIFI) ¿Cómo FLAG?
  • Antecedentes El servicio se mata en android
  • Suscripción o vinculación a un servicio de Intent existente
  • ¿Por qué se reinicia mi servicio de Android cuando se cancela el proceso, aunque utilicé START_NOT_STICKY?
  • Problemas con la vinculación al servicio en Android
  • Por favor, explique algunos conceptos de servicio de Android
  • Android: Leyendo la etiqueta NFC en la clase de servicio
  • ¿Cómo funcionan las aplicaciones de Android, como Facebook, WhatsApp, en primer plano sin notificación?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.