NotificationListenerService和Doze模式以及App Standby

我有一个应用程序,它侦听电话通知,并通过MessageApi将消息发送到Android Wear手表。 除了一些使用Android 6的设备,尤其是华为Mate 8(看起来像所有的华为Android 6都这样做)之外,一切正常。

华为有自己的冻结应用程序的后台处理(受保护的应用程序)的实施。 从用户报告中我已经确认,我的应用程序在华为受保护的应用程序和Android 6的打盹模式中都有例外。 该应用程序工作正常,但正好15分钟后显示了我的应用程序停止发送消息连接到Android Wear手表。 我的应用程序还可以logging收到的通知历史logging,15分钟后没有任何内容到达…直到手机显示屏打开,我的应用程序打开。 之后,手机显示屏closures时应该已经到达的所有通知到达NotificationListenerService实现,并一次发送到手表。 logging的历史logging也证实了这一点。

任何想法如何解决这些手机,尤其是与Android 6的打盹模式华为伴侣8?

当设备处于睡眠模式和/或应用程序处于待机模式时, NotificationListenerService的正确行为是什么?

编辑

用户也确认他们的手机没有处于省电模式,这也影响了后台应用程序及其服务。 这个bug看起来像华为独家,因为没有Nexus用户报告过这个,我的OnePlus One与M没有这样做。 另外N预览在Nexus设备上运行良好。

编辑2

我已经添加了一个可选的前台服务( startForeground() ),所以我的应用程序在通知中心有一个永久通知,因此我的应用程序应该从每个电池优化中排除。 对于前台服务通知,我使用了NotificationCompat.PRIORITY_MIN的优先级,并添加了Notification.FLAG_ONGOING_EVENT标志。 这在华为手机上有所帮助,但不是很多,现在延迟的通知进入我的NotificationListenerService权限后,屏幕打开,而不是打开我的应用程序后。 我不会在NotificationListenerService使用startForeground() ,而是在另一个Service使用startForeground() ,因为我无法控制其生命周期。

Solutions Collecting From Web of "NotificationListenerService和Doze模式以及App Standby"

对于华为设备(不知道是否适用于所有华为设备),您需要申请“受保护的应用”权限才能使您的应用在进入后台时不被冻结。

检测华为设备是否具有“受保护的应用”权限:

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

打开华为保护应用设置页面:

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

不幸的是,我还没有find任何方法来检查用户是否已将您的应用程序授予受保护的应用程序。 请分享,如果有人知道:)

参考: http : //ndroid.info/ldquo_protected_appsrdquo_setting_on_huawei_phones_and_how_to_handle_it

我不知道Android的打盹模式,直到我看到你的post。 然后我看了这篇文章 ,看起来好像是这样的工作! 如果您希望在打盹模式下收到通知,请尝试使用PRIORITY_HIGHPRIORITY_MAX作为您的通知优先级,但即使它起作用,根据文章看来也不是一个完整的解决scheme。