Android8.0通知简单适配
自2019年5月1日起,新上架和预置应用应基于Android 8.0(API等级26)及以上开发。自2019年8月1日起,现有应用的更新应基于Android 8.0(API等级26)及以上开发。八家厂商在签约仪式上郑重承诺:将严格遵守和履行自律公约规定,拒绝上架和更新低API等级应用。
上述是各大Android应用市场发布的公告内容,对于我们开发者来说,不得不将项目的targetSdkVersion提高到至少26以上,API26上的新特性就需要开发者来适配。所以今天就来聊聊在Android8.0上通知的适配。
1、渠道
在8.0上引入了新的概念,渠道和渠道组。
在以往的Android版本中,如果用户将应用的通知关闭后,那么用户就接收不到该应用的所有通知了。但是有的重要通知用户还是希望看到,怎么办。引入渠道这个概念后,就可以轻松的解决这个问题。在8.0上,应用的通知可以分为不同渠道,比如“广告”、“聊天消息”、“推送文章”等等。用户可以根据自己的需要自由选择要接收哪种推送,不想接收的可以关闭。这就不会错过一些重要的通知。
至于渠道组,在渠道创建好了以后,可以将其划分在同一渠道组下(个人感觉没什么卵用啊,有渠道不就好啦)。
2、实现
首先获取NotificationManager:
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
接下来需要定义我们的渠道组:
NotificationChannelGroup group = new NotificationChannelGroup(groupId, groupName);
manager.createNotificationChannelGroup(group);
在构造方法中需要传入两个参数,一个是改渠道组的ID,必须保证唯一,每个渠道组的ID不能用一个。第二个参数是渠道组的名称,这个就可以随便写,不过长度要限制在40个字符以内,太长会被截断,渠道组的名称会在设置页面看到。
有了渠道组,接下来创建渠道:
//创建渠道1
NotificationChannel channel1 = new NotificationChannel(Constants.CHANNEL_ID_1, "渠道1", NotificationManager.IMPORTANCE_HIGH);
channel1.setGroup(Constants.CHANNEL_GROUP_ID_1);
channel1.setDescription("第一个渠道的描述");
//是否使用呼吸灯
channel1.enableLights(true);
//是否允许震动
channel1.enableVibration(true);
//是否显示角标
channel1.setShowBadge(true);
manager.createNotificationChannel(channel1);
在创建渠道的时候需要传入三个参数,渠道ID,需要保证唯一;渠道名称,限制在40个字符以内;最后一个参数渠道的重要等级,需要详细说明下。
/**
* Value signifying that the user has not expressed an importance.
*
* This value is for persisting preferences, and should never be associated with
* an actual notification.
*/
public static final int IMPORTANCE_UNSPECIFIED = -1000;
/**
* A notification with no importance: does not show in the shade.
*/
public static final int IMPORTANCE_NONE = 0;
/**
* Min notification importance: only shows in the shade, below the fold. This should
* not be used with {@link Service#startForeground(int, Notification) Service.startForeground}
* since a foreground service is supposed to be something the user cares about so it does
* not make semantic sense to mark its notification as minimum importance. If you do this
* as of Android version {@link android.os.Build.VERSION_CODES#O}, the system will show
* a higher-priority notification about your app running in the background.
*/
public static final int IMPORTANCE_MIN = 1;
/**
* Low notification importance: shows everywhere, but is not intrusive.
*/
public static final int IMPORTANCE_LOW = 2;
/**
* Default notification importance: shows everywhere, makes noise, but does not visually
* intrude.
*/
public static final int IMPORTANCE_DEFAULT = 3;
/**
* Higher notification importance: shows everywhere, makes noise and peeks. May use full screen
* intents.
*/
public static final int IMPORTANCE_HIGH = 4;
/**
* Unused.
*/
public static final int IMPORTANCE_MAX = 5;
- IMPORTANCE_UNSPECIFIED
不要用这个,会报错。
- IMPORTANCE_NONE
如果设置这个级别,发送通知将不会有任何提示,甚至连该渠道都不会创建(小米手机上)。 - IMPORTANCE_MIN
状态栏不会有小图标,将状态栏拉下来后会看到通知内容,不会有提示音、震动、悬浮、呼吸灯不闪烁。需要注意的是,该级别不适用于创建前台服务的情况,因为前台服务是用户关心的,使用该级别不符合实际情况。如果非设置该级别,那么在api26上,系统会自动将通知设置为一个更高的级别。 - IMPORTANCE_LOW
状态栏显示小图标,将状态栏拉下来后会看到通知内容,不会有提示音、震动、悬浮、呼吸灯不闪烁。 - IMPORTANCE_DEFAULT
状态栏显示小图标,将状态栏拉下来后会看到通知内容,有提示音,没有悬浮、震动、呼吸灯不闪烁。 - IMPORTANCE_HIGH
状态栏显示小图标,将状态栏拉下来后会看到通知内容,有提示音,有悬浮,没有震动、呼吸灯不闪烁。 - IMPORTANCE_MAX
没有用
从上面来看,我们常用的从MIN-HIGH这4种。对于震动和呼吸灯来说需要单独代码开启。但是对于国内的定制Android系统来说,上面统计的几个级别可能不适用,比如在华为系统我们虽然设置了重要级别为IMPORTANCE_HIGH,但就是没有悬浮窗,需要用户去设置里手动开启悬浮。比如在小米系统,明明设置级别为最高,同时开启了震动、提示音、呼吸灯,但就是木有啊!
这里还是建议大家根据实际情况给出重要性级别,同时手动设置开启震动、呼吸灯、提示音等等(根据实际需要),在弹出通知前,判断当前通知所在渠道重要级别,如果符合要求,则跳转到设置页面,让用户自行决定该渠道到底需要怎样提示用户。
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, channelId);
startActivity(intent);
在不同的Android定制系统下,渠道和渠道组的显示不太一样。
小米MIUI
华为EMUI
接下来就是创建一个通知:
public static Notification showSimpleNotification(Context context, String channelId) {
return new Notification.Builder(context, channelId)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("消息的标题" + channelId)
.setContentText("内容内容内容")
.setNumber(10)
.setAutoCancel(true)
.build();
}
跟以往不同的是,在创建通知时需要传入一个渠道ID,这里就用之前创建好的渠道就可以啦。
最后发送一个通知:
manager.notify(random.nextInt(), NotificationFactory.showSimpleNotification(this, channelId));
3、角标
如果想在桌面上APP图标上显示角标的话需要做如下设置:
在创建渠道的时候
//是否显示角标
channel1.setShowBadge(true);
在不同系统上,有的角标是显示一个点,有的是显示具体的未读消息数,根据系统来吧,头疼。
如果想控制每个通知含有具体几条未读消息,可以在创建通知的时候设置,默认是1条。
.setNumber(10)
这样一来,每发送一个该通知就会有10条未读消息。
长按桌面图标会弹出通知内容。
4、删除渠道
如果有的渠道不想要了,官方也提供了删除的方法:
manager.deleteNotificationChannel(Constants.CHANNEL_ID_3);
虽然有的文章说,虽然删除了渠道,但在设置页面也会有记录,可以看到被删除的渠道。但在国内定制系统中,删除后就不会再显示了,设置页面也不会保留。
比如小米手机上删除渠道3后,设置页面如下
所以可以放心大胆的删,不过删除渠道这种情况应该很少遇到吧。
5、最后
如果想看完整项目的话可以移步到github:
https://github.com/GetlingZ/Notification
本人菜鸟一枚,如果文章中有什么不对的地方,欢迎各位指教。