關於Android O 通知渠道總結
本文是關於針對Android O 通知渠道的總結。
Android O 引入了通知渠道Notification Channels,更好的方便使用者管理通知欄訊息。
1 2 3 4 5 6 |
NotificationChannel public final class NotificationChannel extends Object implements Parcelable java.lang.Object ↳ android.app.NotificationChannel |
距離上一次總結通知欄相關的東西好像有很久了,可以去這裡檢視
今天我們從一個基本的通知示例開始,來總結下Android O 通知渠道相關的使用。
基本示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//建立通知欄管理物件 NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); //為了版本相容 選擇V7包下的NotificationCompat進行構造 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); //setTicker 在5.0以上不顯示Ticker屬性資訊 builder.setTicker("狀態列顯示的提示");; //setContentTitle 通知欄通知的標題 builder.setContentTitle("內容標題"); //setContentText 通知欄通知的詳細內容 builder.setContentText("內容文字資訊"); //setAutoCancel 點選通知的清除按鈕是否清除該訊息(true/false) builder.setAutoCancel(true); //setLargeIcon 通知訊息上的大圖示 builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); //setSmallIcon 通知上面的小圖示 builder.setSmallIcon(R.mipmap.ic_launcher);//小圖示 //建立一個意圖 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com")); PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0); //setContentIntent 將意圖設定到通知上 builder.setContentIntent(pIntent); //通知預設的聲音 震動 呼吸燈 builder.setDefaults(NotificationCompat.DEFAULT_ALL); //構建通知 Notification notification = builder.build(); //將構建好的通知新增到通知管理器中,執行通知 mNotificationManager.notify(0, notification); |
這段程式碼很簡單,已經添加了註釋,沒有什麼可以說的。
差異復現
SDK < 8.0(API 26)
這種情況,上面的示例程式碼是能無障礙的將通知訊息顯示出來。
SDK > = 8.0(API 26)
這種情況,上面的示例程式碼,是死活都不會把通知訊息顯示出來的。
在Android Oreo上的開發者選項中,新增加了一個show notification channel warnings的選項功能,可以通過Settings > System> Developer options 下找到開啟。
再次執行程式碼後,介面上會彈出類似於下面的這樣一個Toast,告知你的通知訊息post失敗,詳細情況檢視log
1 2 3 |
Developer warning for package "com.shoewann.notificationsimple" Failed to post notification on channel "null" See log for more details |
檢視log是這樣的:
1 |
E/NotificationService: No Channel found for pkg=com.shoewann.notificationsimple, channelId=null, id=0, tag=null, opPkg=com.shoewann.notificationsimple, callingUid=10083, userId=0, incomingUserId=0, notificationUid=10083, notification=Notification(channel=null pri=0 contentView=null vibrate=default sound=default tick defaults=0xffffffff flags=0x11 color=0x00000000 vis=PRIVATE) |
通過跟蹤檢視相關原始碼,分析到了,在NotificationCompat這個類中的Builder方法。
在版本com.android.support:appcompat-v7:26.1.0的相容庫中,可以看到傳一個引數的Builder(Context context)方法已經過期,使用傳入兩個引數的Builder(@NonNull Context context, @NonNull String channelId)新方法代替。
注意:該新方法需要傳入的這兩個引數都是標註了@NonNull,也就是不能傳入null或者未初始化的變數。
相容程式碼
通過以上的分析,也就是我們在Android Oreo上面使用Notification,就必須要為你的Notification建立一個Notification Channels(通知渠道)。
建立通知渠道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
NotificationCompat.Builder builder = null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("通知渠道ID", "通知渠道名稱", NotificationManager.IMPORTANCE_DEFAULT); channel.enableLights(true); //設定開啟指示燈,如果裝置有的話 channel.setLightColor(Color.RED); //設定指示燈顏色 channel.setShowBadge(true); //設定是否顯示角標 channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);//設定是否應在鎖定螢幕上顯示此頻道的通知 channel.setDescription("通知渠道描述");//設定渠道描述 channel.setVibrationPattern(new long[]{100,200,300,400,500,600});//設定震動頻率 channel.setBypassDnd(true);//設定是否繞過免打擾模式 mNotificationManager.createNotificationChannel(channel); createNotificationChannelGroups(); setNotificationChannelGroups(channel); builder = new NotificationCompat.Builder(this, "通知渠道ID"); builder.setBadgeIconType(BADGE_ICON_SMALL);//設定顯示角標的樣式 builder.setNumber(3);//設定顯示角標的數量 builder.setTimeoutAfter(5000);//設定通知被建立多長時間之後自動取消通知欄的通知。 }else{ builder = new NotificationCompat.Builder(this); } //setContentTitle 通知欄通知的標題 builder.setContentTitle("內容標題"); //setContentText 通知欄通知的詳細內容 builder.setContentText("內容文字資訊"); //setAutoCancel 點選通知的清除按鈕是否清除該訊息(true/false) builder.setAutoCancel(true); //setLargeIcon 通知訊息上的大圖示 builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); //setSmallIcon 通知上面的小圖示 builder.setSmallIcon(R.mipmap.ic_launcher);//小圖示 //建立一個意圖 Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com")); PendingIntent pIntent = PendingIntent.getActivity(this, 1, intent, 0); //setContentIntent 將意圖設定到通知上 builder.setContentIntent(pIntent); //通知預設的聲音 震動 呼吸燈 builder.setDefaults(NotificationCompat.DEFAULT_ALL); //構建通知 Notification notification = builder.build(); //將構建好的通知新增到通知管理器中,執行通知 mNotificationManager.notify(0, notification); |
效果圖:
向右滑動通知訊息,可以顯示延遲本條訊息顯示和設定選項
點選左邊的延遲本條訊息顯示的時間
點選右邊的設定選項,可以顯示進入操作通知的設定入口
在桌面上的快捷方式上會顯示角標
長按快捷方式,會在快捷方式旁邊彈出通知欄視窗,顯示通知欄訊息等資訊。
移除通知渠道
1 2 3 |
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { mNotificationManager.deleteNotificationChannel("通知渠道ID"); } |
跳轉到通知渠道設定
1 2 3 4 5 6 |
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS); intent.putExtra(Settings.EXTRA_CHANNEL_ID, "通知渠道ID"); intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName()); startActivity(intent); } |
建立通知渠道組
1 2 3 |
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { mNotificationManager.createNotificationChannelGroup(new NotificationChannelGroup("通知渠道組ID", "通知渠道組名稱")); } |
繫結通知渠道組
1 2 3 |
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { channel.setGroup("通知渠道組ID"); } |