從 Android API 級別 26 開始,應用程式必須使用持續通知 前景服務這項規定是為了避免您隱藏使用者 幹擾系統資源需求過多的服務,包括 或電池的續航力這項規定會產生潛在問題:如果應用程式 擁有多項前景服務時,並不會謹慎管理通知, 因此同一個叢集內 無法關閉的通知,導致使用中的通知雜亂無章 通知。
使用 Navigation 等 SDK 時,這個問題會更加棘手
SDK,這類 SDK 是用於執行前景服務,不受
因此會造成獨立永久通知,導致系統難以整合。
為解決這些問題,Navigation SDK 1.11 版推出了簡單的 API
可協助您管理應用程式 (包括 SDK 中) 的持續通知。
元件
前景服務管理工具提供 Android 前景的包裝函式 服務類別以及永久通知類別這個包裝函式的主要 函式,強制重複使用通知 ID, 使用該工具在所有前景服務中共用相同資源。
Navigation SDK 包含用於初始化及取得
ForegroundServiceManager
單例模式。這個單例模式只能初始化
只需在 Navigation SDK 生命週期內執行一次因此,如果您使用了
初始化呼叫 (initForegroundServiceManagerMessageAndIntent()
或
initForegroundServiceManagerProvider()
),則您應該
並加上 try-catch 區塊,這樣系統才能重新輸入該路徑Navigation SDK
會在您多次呼叫任何方法時擲回執行階段例外狀況,除非您
請先清除 ForegroundServiceManager
的所有參照,並呼叫
再呼叫 clearForegroundServiceManager()
。
initForegroundServiceManagerMessageAndIntent()
的四個參數是
application
、notificationId
、defaultMessage
和resumeIntent
。如果
最後三個參數為空值,接著通知是標準參數
Navigation SDK 通知。你仍然可以隱藏其他前景
選用 Google Cloud 服務notificationId
參數
指定應用於通知的通知 ID。如果是
空值,則會使用任意值。您可以明確設定這項功能
與其他通知發生衝突,比如其他 SDK 的通知。
defaultMessage
是系統未
導航。resumeIntent
是通知時觸發的意圖
即可。如果 resumeIntent
為空值,請按一下通知
系統會忽略此值。
initForegroundServiceManagerProvider()
的三個參數為
application
、notificationId
和notificationProvider
。如果最終結果為
兩個參數為空值,則通知是標準 Navigation SDK
通知。notificationId
參數會指定通知 ID
通知。如果值為空值,任意值會是
您可以明確調整設定,以解決與其他
像是來自其他 SDK 的通知如果 notificationProvider
是
供應商就必須負責
產生要顯示的通知
Navigation SDK getForegroundServiceManager()
方法會傳回
前景服務管理工具單例模式如果您尚未產生憑證
這相當於呼叫 initForegroundServiceManagerMessageAndIntent()
含有空值參數 (適用於 notificationId
、defaultMessage
和
resumeIntent
。
ForegroundServiceManager
有三個簡單方法。前兩個用於
將服務移入及移出前景,通常都是從
建立位於建立的 Service 中使用這些方法可確保
都會與共用永久通知建立關聯最後一個
方法 updateNotification()
,會標記通知含有通知的管理員
並應重新轉譯。
如果您需要完全控管共用永久通知:
API 提供的 NotificationContentProvider
介面可用來定義
通知提供者,內含接收通知的一種方法
與目前內容互動此 API 也提供基礎類別,您可以
視需要用來定義供應器基礎類別的主要類別之一
就是可以讓您呼叫 updateNotification()
必須存取 ForegroundServiceManager
。如果您使用
通知供應商以便接收新的通知訊息,您可以呼叫
內部方法來在通知中顯示訊息。
使用情境
本節詳細說明使用共用永久儲存空間的情境 通知。
- 隱藏其他應用程式前景服務的持續通知
- 最簡單的情境是保留目前行為,並只使用
轉譯 Navigation SDK 資訊的永久通知。其他服務
使用前景服務管理工具,即可隱藏這則通知背後的內容
startForeground()
和stopForeground()
方法。 - 隱藏其他應用程式前景服務的持續通知,但已設定 未導航時顯示的預設文字
- 第二個最簡單的情況是保留目前行為,並僅使用
轉譯 Navigation SDK 資訊的常駐通知,但不包括
並在系統沒有導航的情況下顯示系統沒有進行導覽時
提供給
initForegroundServiceManagerMessageAndIntent()
的字串 ,而不是先前提到的 「Google 地圖」。您也可以使用此呼叫設定重新啟用意圖 使用者點擊通知時觸發。 - 完全掌控持續性通知的顯示設定
- 最後一個情境需要定義並建立通知供應器
並使用以下指令將其傳遞至
ForegroundServiceManager
initForegroundServiceManagerProvider()
。這個選項可讓您 通知頁面顯示的內容完全由您掌控 中斷 Navigation SDK 通知資訊與 此時,系統會移除 通知。Google 並不提供簡單的方式讓您擷取此資訊 資訊,並將資訊插入通知中。
通知提供者範例
以下程式碼範例示範如何建立及傳回通知 透過簡單的通知內容供應器
public class NotificationContentProviderImpl
extends NotificationContentProviderBase
implements NotificationContentProvider {
private String channelId;
private Context context;
private String message;
/** Constructor */
public NotificationContentProviderImpl(Application application) {
super(application);
message = "-- uninitialized --";
channelId = null;
this.context = application;
}
/**
* Sets message to display in the notification. Calls updateNotification
* to display the message immediately.
*
* @param msg The message to display in the notification.
*/
public void setMessage(String msg) {
message = msg;
updateNotification();
}
/**
* Returns the notification as it should be rendered.
*/
@Override
public Notification getNotification() {
Notification notification;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Spanned styledText = Html.fromHtml(message, FROM_HTML_MODE_LEGACY);
String channelId = getChannelId(context);
notification =
new Notification.Builder(context, channelId)
.setContentTitle("Notifications Demo")
.setStyle(new Notification.BigTextStyle()
.bigText(styledText))
.setSmallIcon(R.drawable.ic_navigation_white_24dp)
.setTicker("ticker text")
.build();
} else {
notification = new Notification.Builder(context)
.setContentTitle("Notification Demo")
.setContentText("testing non-O text")
.build();
}
return notification;
}
// Helper to set up a channel ID.
private String getChannelId(Context context) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
if (channelId == null) {
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel(
"default", "navigation", NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("For navigation persistent notification.");
notificationManager.createNotificationChannel(channel);
channelId = channel.getId();
}
return channelId;
} else {
return "";
}
}
}
建立 NotificationContentProviderImpl
後,請將
使用下列程式碼導覽 SDK:
ForegroundServiceManager f = NavigationApi.getForegroundServiceManager(getApplication());
mNotification = new NotificationContentProviderImpl(getApplication());
NavigationApi.clearForegroundServiceManager();
NavigationApi.initForegroundServiceManagerProvider(getApplication(), null, mNotification);
注意事項與未來計畫
- 請務必盡早呼叫
initForegroundServiceManagerMessageAndIntent()
或initForegroundServiceManagerProvider()
,以便 定義了預期用途您必須呼叫此方法 再建立新的導覽器 - 請務必找出呼叫
initForegroundServiceManagerMessageAndIntent()
或initForegroundServiceManagerProvider()
(如果程式碼路徑為 重複輸入。在 Navigation SDK 2.0 版中,呼叫此方法 多次擲回已檢查的例外狀況,而非執行階段例外狀況。 - Google 可能還要做一些努力,才能使樣式更加一致 符合標頭樣式的通知的生命週期。
- 定義通知供應程式時,您可以控制抬頭通知行為 與優先權
- Google 無法提供簡便的即時路線擷取方法 通知供應程式可能插入通知中的資訊。