安卓8.0通知許可權適配
隨著安卓8.0的出現,越來越多的人開始要進行8.0系統的適配了,很多人都知道安卓最近幾個版本的新特性這裡大概說一下:
- 5.0的時候出現了Design風格
- 6.0出現的危險許可權需要申請
- 7.0出現的目錄訪問被限制
- 今天要介紹的8.0通知欄的機制
列印下來的錯誤資訊: No Channel found for pkg=com.lixuc.demo, channelId=null, id=1, tag=null, opPkg=com.lixuc.demo, callingUid=10081, userId=0, incomingUserId=0, notificationUid=10081, notification=Notification(channel=null pri=0 contentView=null vibrate=default sound=null defaults=0x2 flags=0x10 color=0xff98903b vis=PRIVATE)
跟進NotificationManager的notify方法,呼叫了NotificationManagerService的enqueueNotificationWithTag將通知入隊,最後在NotificationManagerService的enqueueNotificationInternal方法中發現了error log的蹤跡,擷取程式碼片如下圖:
見圖可知,是由於此條通知沒有查詢到應用中對應的NotificationChannel的原因,而無法彈出來。那NotificationChannel是個什麼鬼,查閱官文得知,這是Android O新增的通知渠道,其允許您為要顯示的每種通知型別建立使用者可自定義的渠道。使用者介面將通知渠道稱之為通知類別。
先貼出我猜到坑的錯誤程式碼:
這裡的NotificationCompat及NotificationManagerCompat來自官方提供的相容庫:
com.android.support:appcompat-v7:26.1.0
想著最新的Compat庫相容應該做得是最好的,然後錯就錯在這句程式碼:
NotificationCompat.Builder(context, Integer.toString(notificationId));
一眼看到Builder建構函式的第二個引數,傳的是id,就直接把notificationId傳進去了,其實細看傳的是channelId,我這裡把channelId和notificationId概念搞混了。channelId傳null,或者只有一個引數的Builder的構造方法,都不會出現錯誤,修正程式碼如下:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, null);
//或者
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
- 1
- 2
- 3
- 4
原理就是:NotificationChannel是Android O新增的特性,為了相容老程式碼,如果channelId為null的話,Android O會把通知歸到“Other Channel”上。
PS:將targetSdkVersion提到26以上的話,就必須設定channel了,不能為null。
下面來說一下我的解決方法
首先建立channel資訊:
如果你需要傳送屬於某個自定義渠道的通知,你需要在傳送通知前建立自定義通知渠道,示例如下:
NotificationChannel channel = new NotificationChannel("1",
"Channel1", NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true); //是否在桌面icon右上角展示小紅點
channel.setLightColor(Color.RED); //小紅點顏色
channel.setShowBadge(true); //是否在久按桌面圖示時顯示此渠道的通知
然後建立通知後,向自定義渠道傳送通知
int notificationId = 0x1234;
Notification.Builder builder = new Notification.Builder(context,"1"); //與之前建立的channelId對應
//icon title text必須包含,不然影響桌面圖示小紅點的展示
builder.setSmallIcon(android.R.drawable.stat_notify_chat)
.setContentTitle("xxx")
.setContentText("xxx")
.setNumber(3); //久按桌面圖示時允許的此條通知的數量
notificationManager.notify(notificationId, builder.build());
刪除掉某個渠道:NotificationChannel mChannel = mNotificationManager.getNotificationChannel(id);
mNotificationManager.deleteNotificationChannel(mChannel);
如果你的應用裡面有通知的話,恰巧你的targetSdkVersion是26以上的情況下,你就需要進行以上的操作了
大家都有了以上相同的教程,但是人和人之間的區別在於:別人有顆更強大的內心,可怕的是比你聰明的人比你還要更努力!!
當你下定決心,準備前行的時候,剩下的只有堅持了。。。
如果大家覺得我寫的還可以的話,請關注我的微信公眾號: