不得不说Andoird的通知栏相比于IOS在使用上有着明显的不足,不仅是体验上的差异,还有大量的非关注通知铺满了通知栏,导致通知栏混乱,杂多。
为什么一个很好的通知栏功能现在却变得这么遭用户讨厌?很大一部分原因都是因为开发者没有节制地使用导致的。每个开发者都只想着尽可能地去宣传自己的App,最后用户的手机就乱得跟鸡窝一样了。但是通知栏又还是有用处的,比如我们收到微信、短信等消息的时候,确实需要通知栏给我们提醒。因此分析下来,通知栏目前最大的问题就是,无法让用户对感兴趣和不感兴趣的消息进行区分。就比如说,我希望淘宝向我推送卖家发货和物流的相关消息,但是我不想收到那些打折促销或者是让我去买衣服的这类消息。那么就目前来说,是没有办法对这些消息做区分的,我要么同意接受所有消息,要么就屏蔽所有消息,这是当前通知栏的痛点。
那么在Android 8.0系统中,Google也是从这个痛点开始下手的。
通知渠道:
什么是通知渠道呢?顾名思义,就是每条通知都要属于一个对应的渠道。每个App都可以自由地创建当前App拥有哪些通知渠道,但是这些通知渠道的控制权都是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动、或者是否要关闭这个渠道的通知。
拥有了这些控制权之后,用户就再也不用害怕那些垃圾推送消息的打扰了,因为用户可以自主地选择自己关心哪些通知、不关心哪些通知。举个具体的例子,我希望可以即时收到支付宝的收款信息,因为我不想错过任何一笔收益,但是我又不想收到支付宝给我推荐的周围美食,因为我没钱只吃得起公司食堂。这种情况,支付宝就可以创建两种通知渠道,一个收支,一个推荐,而我作为用户对推荐类的通知不感兴趣,那么我就可以直接将推荐通知渠道关闭,这样既不影响我关心的通知,又不会让那些我不关心的通知来打扰我了。
通知渠道推出后,在8.0以上的Android手机是无法通过过往的API发布通知至通知栏的。需要创建通知渠道,然后在构建通知的时候引入通知渠道才可以。
如何创建通知渠道?
- 首先,确保你的targetSdkVersion已经指定到26或者更高。文件位于app/build.gradle。
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.mintu.dcdb"
minSdkVersion 19
targetSdkVersion 27
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
- 然后编码固定通知渠道构建方法,在运用时调用,笔者是在Service中发送的通知:
/**
* 8.0以上手机需要构建通知渠道,才能够打开通知栏
* @param channelId 通知栏id
* @param channelName 通知栏名
* @param importance 通知栏级别 例如NotificationManager.IMPORTANCE_HIGH;
*/
@TargetApi(Build.VERSION_CODES.O)
public void createNotificationChannel(String channelId, String channelName, int importance) {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
NotificationManager notificationManager = (NotificationManager) mC.getSystemService(
NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}else{
Log.e(TAG,"Android版本低于26,无需创建通知渠道");
}
}
通知栏级别分5级,笔者用了最高级NotificationManager.IMPORTANCE_MAX
,该常量值为5,代表通知会显示悬浮框、有声音有震动,并且陈列在通知栏中。一共有5个等级,常量值为1至5。
public void sendNotification(String title,String content,String notificationChannel){
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mC,notificationChannel).setSmallIcon(R.mipmap.app_icon)
// 设置图标
.setContentTitle(title)
.setContentText(content)
.setTicker(mC.getString(R.string.app_name)+"为您推送了一条新的信息\n" + content)
.setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
// .setOngoing(true)
.setFullScreenIntent(null, false)
.setDefaults(Notification.DEFAULT_ALL)
// .setVisibility(Notification.VISIBILITY_PUBLIC)
.setPriority(Notification.PRIORITY_MAX);
Intent resultIntent = new Intent();
resultIntent.putExtra("isMesg", true);
resultIntent.setClass(mC, MainView.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mC, 0,
resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
Notification notification = mBuilder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(Constant.SYSTEM_NOTIFYID, notification);
}
发送方法与以前没有什么差别,只要急着在构建Builder的时候将我们创建好的通知渠道ID传入就可以了。
使用代码:
//初始化并且创建通知渠道
private final String MESSAGE_CHANNELID="message";
private final String MESSAGE_CHANNELNAME="督办消息";
notificationUtil=new NotificationUtil(this);
notificationUtil.createNotificationChannel(MESSAGE_CHANNELID,MESSAGE_CHANNELNAME, NotificationManager.IMPORTANCE_MAX);
//发送通知
String title = "目标督办";
notificationUtil.sendNotification(title,getNewstContent(msgListInfo),MESSAGE_CHANNELID);