1. 程式人生 > >關於Android O 通知渠道總結

關於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 > SystemDeveloper 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);

效果圖:

android-o-notification-channel-1

向右滑動通知訊息,可以顯示延遲本條訊息顯示和設定選項

android-o-notification-channel-2

點選左邊的延遲本條訊息顯示的時間

android-o-notification-channel-3

點選右邊的設定選項,可以顯示進入操作通知的設定入口

android-o-notification-channel-4

在桌面上的快捷方式上會顯示角標

android-o-notification-channel-6

長按快捷方式,會在快捷方式旁邊彈出通知欄視窗,顯示通知欄訊息等資訊。

android-o-notification-channel-7

移除通知渠道

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);

}

android-o-notification-channel-5

建立通知渠道組

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");

}