Режим NotificationListenerService и Doze и App Standby

У меня есть приложение, которое прослушивает уведомления по телефону и отправляет сообщение на Android Wear через MessageApi . Все работает хорошо, за исключением некоторых устройств с Android 6, особенно Huawei Mate 8 (похоже, что все Huawei Android 6 делают это).

У Huawei есть своя реализация фоновой обработки замороженных приложений (защищенные приложения). Из отчетов пользователей я подтвердил, что мое приложение имеет исключения в защищенных приложениях Huawei, а также в режиме Doz Android 6. Приложение работает нормально, но через ровно 15 минут с отображением моего приложения прекращается отправка сообщений на подключенные часы Android Wear. Мое приложение также может записывать полученную историю уведомлений, и ничего не приходит после 15 минут … пока дисплей телефона не будет включен, и мое приложение будет открыто. После этого все уведомления, которые должны были появиться, когда дисплей телефона был выключен, вошли в мою реализацию NotificationListenerService и сразу отправлены на часы. Это также подтверждается записанной историей.

Любые идеи, как исправить это для этих телефонов, особенно Huawei Mate 8 с Android 6 с режимом Doze?

Каково правильное поведение службы NotificationListenerService когда устройство находится в режиме доз и / или приложение находится в режиме ожидания?

РЕДАКТИРОВАТЬ

Пользователи также подтвердили, что их телефоны не находятся в режиме энергосбережения, что также влияет на фоновые приложения и их услуги. Эта ошибка выглядит как эксклюзивная Huawei, потому что пользователи Nexus не сообщили об этом, и мой OnePlus One с M тоже не делает этого. Также N превью хорошо работает на устройствах Nexus.

EDIT 2

Я добавил дополнительную службу переднего плана ( startForeground() ), поэтому мое приложение имеет постоянное уведомление в центре уведомлений, поэтому мое приложение должно быть исключено из каждой оптимизации батареи. Для уведомления об обслуживании переднего плана я использовал приоритет NotificationCompat.PRIORITY_MIN и я добавил флаг Notification.FLAG_ONGOING_EVENT . Это немного помогло на телефонах Huawei, но не так много, теперь отложенные уведомления поступают в мою NotificationListenerService сразу после включения экрана, после открытия моего приложения. Я не использую startForeground() в моей Service NotificationListenerService а в другой Service потому что у меня нет контроля над ее жизненным циклом.

Solutions Collecting From Web of "Режим NotificationListenerService и Doze и App Standby"

Для устройств Huawei (не уверен, что это относится ко всем устройствам Huawei) вам необходимо запросить разрешение для защищенных приложений, чтобы ваше приложение не зависало, когда оно попадает в фоновый режим.

Чтобы определить, имеет ли устройство Huawei разрешение «Защищенные приложения»:

 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; } 

Чтобы открыть страницу настроек защищенных приложений 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 ""; } 

К сожалению, я не нашел способа проверить, предоставил ли пользователь ваше приложение в качестве защищенного приложения. Пожалуйста, поделитесь, если кто-нибудь знает 🙂

Ссылка: http://ndroid.info/ldquo_protected_appsrdquo_setting_on_huawei_phones_and_how_to_handle_it

Я не знал о режиме Doz в Android до тех пор, пока не увидел ваш пост. Затем я прочитал эту статью, и, похоже, именно так она и должна работать! Если вы хотите получать уведомления в режиме Doze, попробуйте использовать PRIORITY_HIGH или PRIORITY_MAX для вашего приоритета уведомлений, но даже если он работает, на самом деле это не похоже на полное решение в соответствии с этой статьей.