Android 8.0 引入了通知管道,其允許您為要顯示的每種通知類型建立使用者可自定義的管道。使用者界面将通知管道稱之為通知類别。targeSdk更新到26之後,所有的通知的實作都需要提供通知管道,如果不提供通知管道的話,所有通知在8.0系統上面都不能正常展示,下面來看代碼。
既然是相容,當然不能少了判斷系統版本了:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // 大于等于 8.0 系統版本
}else { // 低于8.0 版本
}
針對8.0以上的版本 注意 建立 NotificationChannel , 并設定其建立同一 channelId,注意 這個id不能過長, 過長可能被截斷;
private final String NOTIFICATION_CHANNEL_NAME = "Service";
private final String NOTIFICATION_DESCRIPTION = "讀取位置資訊";
private NotificationManager notificationManager = null;
private NotificationChannel notificationChannel = null;
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Android O上對Notification進行了修改,如果設定的targetSDKVersion>=26建議使用此種方式建立通知欄
if (null == notificationManager) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
String channelId = "channel";
if (notificationChannel == null) {
notificationChannel = new NotificationChannel(channelId,
NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription(NOTIFICATION_DESCRIPTION);
// 設定通知出現時的閃燈(如果 android 裝置支援的話)
notificationChannel.enableLights(true);
notificationChannel.setLightColor(0);
notificationManager.createNotificationChannel(notificationChannel);
}
mBuilder.setChannel(channelId);
}
mBuilder.setPriority(0);// 設定該通知優先級
mBuilder.setSmallIcon(R.mipmap.logo);
mBuilder.setContentTitle(getString(R.string.app_name));
mBuilder.setContentText(getString(R.string.app_runing));
mBuilder.setContentIntent(intent);
notification = mBuilder.build();
startForeground(ServiceID.ID, notification);
在這裡 我所相容的8.0以上機型, 通過這樣設定channel 還是會彈出 錯誤資訊:“Failed to post notification on channel "null"”;
這裡都是通過 v7包下的 NotificationCompat 建立,怎麼還會報錯并且報錯 指代的是 notification on channel null????
于是我們這樣更新一下代碼,針對8.0的 做另一種設定 channel方式:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Android O上對Notification進行了修改,如果設定的targetSDKVersion>=26建議使用此種方式建立通知欄
if (null == notificationManager) {
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
String channelId = "channel";
if (notificationChannel == null) {
notificationChannel = new NotificationChannel(channelId,
NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
notificationChannel.setDescription(NOTIFICATION_DESCRIPTION);
// 設定通知出現時的閃燈(如果 android 裝置支援的話)
notificationChannel.enableLights(true);
notificationChannel.setLightColor(0);
notificationManager.createNotificationChannel(notificationChannel);
}
// 這裡 針對8.0 我們如下設定 channel
notification = new Notification.Builder(this.getApplicationContext(),channelId)
.setSmallIcon(R.mipmap.logo)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.app_runing)).build();
}else {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setPriority(0);// 設定該通知優先級
mBuilder.setSmallIcon(R.mipmap.logo);
mBuilder.setContentTitle(getString(R.string.app_name));
mBuilder.setContentText(getString(R.string.app_runing));
notification = mBuilder.build();
}
startForeground(ServiceID.ID, notification);
因為跟很多文章描述的問題不同,在此記錄讓大家參考一下。 8.0一下 通過 NotificationCompat 設定, 8.0以及以上 通過Notification 設定, 然後大家也發現 Notification 在 8.0 以後 廢棄了 一個參數的構造方法, 取代的就是多了一個 channel 的構造方法。