NotificationListenerService y modo Doze y modo de espera de aplicación

Tengo una aplicación que escucha las notificaciones de teléfono y envía un mensaje a un reloj de Android Wear a través de MessageApi . Todo funciona bien excepto en algunos dispositivos con Android 6, especialmente Huawei Mate 8 (parece que todos los Android 6 de Huawei hacen esto).

Huawei tiene su propia aplicación de congelación de aplicaciones de procesamiento de fondo (aplicaciones protegidas). De los informes de los usuarios, he confirmado que mi aplicación tiene una excepción en las aplicaciones protegidas de Huawei y también en el modo Doze de Android 6. La aplicación funciona correctamente, pero después de exactamente 15 minutos con la visualización de mi aplicación deja de enviar mensajes al reloj Android Wear conectado. Mi aplicación también puede registrar el historial de notificaciones recibidas y nada llega después de los 15 minutos … hasta que se encienda la pantalla del teléfono y se abra mi aplicación. Después de que todas las notificaciones que deberían haber llegado mientras la pantalla del teléfono estaba apagado llegan a mi implementación de NotificationListenerService y se envían al reloj, de una vez. Esto también se confirma con la historia registrada.

Cualquier idea de cómo arreglar esto para estos teléfonos, especialmente el Huawei Mate 8 con Android 6 con Doze modo?

¿Cuál es el comportamiento correcto de NotificationListenerService mientras el dispositivo está en el modo doze y / o la aplicación está en el modo de espera?

EDITAR

Los usuarios también han confirmado que sus teléfonos no están en un modo de ahorro de energía que también afecta a las aplicaciones de fondo y sus servicios. Este error parece exclusivo de Huawei porque ningún usuario de Nexus ha informado de ello y mi OnePlus One con M no está haciendo esto tampoco. También la vista previa N funciona bien en dispositivos Nexus.

EDIT 2

He añadido un servicio de primer plano opcional ( startForeground() ) para que mi aplicación tenga una notificación permanente en el centro de notificación, por lo tanto mi aplicación debe excluirse de cada optimización de la batería. Para la notificación de servicio de primer plano utilicé una prioridad de NotificationCompat.PRIORITY_MIN y añadí el indicador Notification.FLAG_ONGOING_EVENT . Esto ayudó un poco en los teléfonos de Huawei, pero no mucho, ahora las notificaciones retrasadas llegan a mi NotificationListenerService después de que la pantalla está encendida después de abrir mi aplicación. No utilizo el startForeground() en mi NotificationListenerService pero en otro Service porque no tengo control sobre su ciclo de vida.

Para los dispositivos de Huawei (no está seguro si se aplica a todos los dispositivos Huawei), debe solicitar el permiso de Aplicaciones protegidas para que su aplicación no se congela cuando pasa al fondo.

Para detectar si un dispositivo de Huawei tiene el permiso Protected Apps:

 private boolean hasProtectedAppsSetting() { Intent intent = new Intent(); intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity"); List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return list.size() > 0; } 

Para abrir la página de configuración de aplicaciones protegidas de Huawei:

 private void showProtectedAppsSetting() { try { String cmd = "am start -n com.huawei.systemmanager/.optimize.process.ProtectActivity"; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { cmd += " --user " + getUserSerial(); } Runtime.getRuntime().exec(cmd); } catch (IOException ignored) { } } private String getUserSerial() { //noinspection ResourceType Object userManager = getSystemService("user"); if (null == userManager) return ""; try { Method myUserHandleMethod = android.os.Process.class.getMethod("myUserHandle", (Class<?>[]) null); Object myUserHandle = myUserHandleMethod.invoke(android.os.Process.class, (Object[]) null); Method getSerialNumberForUser = userManager.getClass().getMethod("getSerialNumberForUser", myUserHandle.getClass()); long userSerial = (Long) getSerialNumberForUser.invoke(userManager, myUserHandle); return String.valueOf(userSerial); } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException ignored) { } return ""; } 

Lamentablemente, no he encontrado ninguna forma de comprobar si el usuario ha concedido su aplicación como una aplicación protegida. Por favor comparta si alguien sabe 🙂

Referencia: http://ndroid.info/ldquo_protected_appsrdquo_setting_on_huawei_phones_and_how_to_handle_it

No sabía sobre el modo Doze de Android hasta que vi tu publicación. Entonces leo este artículo y parece que es así como se supone que funciona! Si desea recibir notificaciones durante el modo Doze, intente utilizar PRIORITY_HIGH o PRIORITY_MAX para su prioridad de notificación, pero incluso si funciona, no parece una solución completa según el artículo.

  • No se puede conectar el emulador de Android Wear con el dispositivo
  • El cuadro de selección de dispositivos Android Wear dice "localhost offline: 4444 minSdk (API 20)> deviceSdk (API 1)"
  • Detectar Moto 360 / circlular forma y onApplyWindowInsetListener no se llama
  • Android Wear: Inicio de un servicio en la computadora de mano
  • Android Studio módulos de proyecto "móviles" y "desgaste", ubicación de componentes compartidos
  • ¿Dónde están los archivos de salida de Android Wear Proguard?
  • Registro de pantalla Android Wear
  • Cara de reloj personalizada para Android Wear
  • Android Wear - Notificación - setContentAction () no funciona
  • "Actividad predeterminada no encontrada" para una aplicación portátil creada con la plantilla de Android Studio
  • Los comandos de voz no funcionan en el equipo de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.