9

我有監聽電話通知,並通過MessageApi將消息發送到Android Wear手錶的應用程序。除了一些使用Android 6的設備,尤其是華爲Mate 8(看起來像所有的華爲Android 6都這麼做),一切都運行良好。NotificationListenerService和打盹模式和應用待機

華爲有自己的執行凍結的應用程序後臺處理(受保護的應用程序)的。從用戶報告中我已經確認,我的應用程序在華爲受保護的應用程序以及Android 6的Doze模式中都有例外。該應用程序可以正常工作,但在顯示完15分鐘後,我的應用程序停止向連接的Android Wear手錶發送消息。我的應用程序還可以記錄收到的通知歷史記錄,並在15分鐘後沒有任何內容到達......直到手機顯示屏打開並且我的應用程序打開。之後,手機顯示屏關閉時應該到達的所有通知都會到達我的NotificationListenerService實施中,並會一次發送到手錶。記錄的歷史記錄也證實了這一點。

任何想法如何解決這一問題的這些手機,尤其是華爲伴侶8與Android 6打盹模式?

什麼NotificationListenerService的正確行爲,而該設備處於休眠模式和/或應用處於待機模式?

編輯

用戶也證實,他們的電話是不是省電模式,也影響到後臺應用程序及其服務。這個bug看起來像華爲的獨家,因爲沒有Nexus用戶報告過這個,我的OnePlus One與M也沒有這樣做。此外N預覽適用於Nexus設備。 2

我添加可選服務前景(startForeground()),所以我的應用程序具有在通知中心的永久通知

EDIT,因而我的應用程序應被排除從每一個電池優化。對於前臺服務通知,我使用了NotificationCompat.PRIORITY_MIN的優先級,並添加了Notification.FLAG_ONGOING_EVENT標誌。這對華爲手機有所幫助,但不是太多,現在延遲通知在屏幕打開後立即到達我的NotificationListenerService,而不是在打開我的應用程序之後。我的NotificationListenerService中不使用startForeground(),而是使用另一個Service,因爲我無法控制其生命週期。

回答

0

我不知道Android的打盹模式,直到我看到您的帖子。然後我讀了this article,看來這就是它應該如何工作!如果您希望在打盹模式下收到通知,請嘗試使用PRIORITY_HIGHPRIORITY_MAX來獲得通知優先級,但即使它起作用,根據文章看來,它也不是一個完整的解決方案。

+0

這文章是關於推送通知,而不是本地通知。我的應用沒有服務器,它完全脫機,所以我無法通過高優先級推送通知喚醒電話。當電話顯示通知時,也不可能向電話發送推送通知... – shelll

+0

根據文章,是的,您將無法喚醒設備 – NecipAllef

2

對於華爲的設備(不知道是否適用於所有在華爲設備上),你需要爲了保護對應用程序的權限請求您的應用程序時,它進入後臺不被凍結。

要檢測一個華爲設備已受保護的應用程序權限:

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

+0

感謝您提供此信息。但是,正如問題中提到的那樣,問題在於,即使我的應用程序在華爲受保護的應用程序中出現異常,也無法解決「背景凍結」問題。即使在禁用Android 6的本地電池優化以及前臺服務的情況下也是如此。對於某些用戶來說,向受保護的應用程序和電池優化添加例外就足夠了,但不是全部。即使是大多數。 – shelll