[英]NotificationListenerService and Doze mode and App Standby
我有一個應用程序,可以收聽電話通知,並通過MessageApi
向Android Wear手表發送消息。 一些設備運行良好,除了Android 6的一些設備,特別是華為Mate 8(看起來像所有華為Android 6的這樣做)。
華為有自己的凍結應用程序后台處理(受保護的應用程序)的實現。 從用戶報告中我已經確認我的應用程序在華為的受保護應用程序和Android 6的打盹模式中都有例外。 該應用程序工作正常,但在顯示關閉15分鍾后,我的應用程序停止向連接的Android Wear手表發送消息。 我的應用程序還可以記錄收到的通知歷史記錄,15分鍾后沒有任何內容...直到手機的顯示屏打開並且我的應用程序打開。 之后,在手機顯示屏關閉時應該到達的所有通知都會到達我的NotificationListenerService
實現並立即發送到手表。 記錄的歷史也證實了這一點。
任何想法如何為這些手機解決這個問題,尤其是帶有Doze模式的Android 6的華為Mate 8?
當設備處於打盹模式和/或應用程序處於待機模式時, NotificationListenerService
的正確行為是什么?
編輯
用戶還確認他們的手機未處於省電模式,這也會影響后台應用及其服務。 這個bug看起來像華為獨家,因為沒有Nexus用戶報告這個,我的OnePlus One和M也沒有這樣做。 N預覽也適用於Nexus設備。
編輯2
我添加了一個可選的前台服務( startForeground()
),因此我的應用程序在通知中心有一個永久通知,因此我的應用程序應該從每個電池優化中排除。 對於前台服務通知,我使用了NotificationCompat.PRIORITY_MIN
的優先級,並添加了Notification.FLAG_ONGOING_EVENT
標志。 這對華為手機有點幫助但不多,現在延遲通知在打開我的應用后打開屏幕后立即進入我的NotificationListenerService
。 我不在我的NotificationListenerService
使用startForeground()
,而是在另一個Service
因為我無法控制其生命周期。
對於華為設備(不確定是否適用於所有華為設備),您需要申請受保護的應用程序權限,以便您的應用程序在進入后台時不會凍結。
檢測華為設備是否具有受保護的應用程序權限:
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 "";
}
不幸的是,我沒有找到任何方法來檢查用戶是否已將您的應用程序授予受保護的應用程序。 請分享,如果有人知道:)
參考: http : //ndroid.info/ldquo_protected_appsrdquo_setting_on_huawei_phones_and_how_to_handle_it
在看到你的帖子之前,我不知道Android的Doze模式。 然后我讀了這篇文章 ,看起來它應該是如何工作的! 如果您想在打盹模式下收到通知,請嘗試使用PRIORITY_HIGH
或PRIORITY_MAX
作為通知優先級,但即使它起作用,根據文章它似乎並不是一個完整的解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.