首先,对于Android8.0以上版本系统的通知功能,仅仅靠NoticeficationCompat.Builder已经不能实现了,因为8.0以后引入了一个通道的概念---NotificationChannel.如果在8.0以上系统没有使用通道的概念,你将会发现有好多属性即使build()了,但是仍然不起作用。所以一定要重视通道如何使用。
所谓通道:就是每条通知都要属于一个对应的渠道。每个App都可以自由地创建当前App拥有哪些通知渠道,但是这些通知渠道的控制权都是掌握在用户手上的。用户可以自由地选择这些通知渠道的重要程度,是否响铃、是否振动、或者是否要关闭这个渠道的通知
实现通知栏功能,需要两个类Notification和NotificationManager两个类
NotificationManager:主要负责状态栏通知的管理类,负责发通知、清除通知。
代码中用到的相关的属性和方法
PendingIntent(表示一个在将来某个待定的时刻发生,而Intent是立刻发生)位标识符:
FLAG_ONE_SHOT: 返回的PendingIntent只能够执行一次,执行完成后就会自动消除。
FLAG_NO_CREATE: 如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL
FLAG_CANCEL_CURRENT: 相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景
FLAG_UPDATE_CURRENT: 更新的PendingIntent
通知栏的优先级:
Notification.PRIORITY_DEFAULT:默认优先级用于没有特殊优先级分类的通知
Notification.PRIORITY_HIGH:高优先级用于重要的通信内容,例如短消息或者聊天,这些都是对用户来说比较有兴趣的。
Notification.PRIORITY_LOW:低优先级可以通知用户但又不是很紧急的事件
Notification.PRIORITY_MAX:重要而紧急的通知,通知用户这个事件是时间上紧迫的或者需要立即处理的
Notification.PRIORITY_MIN:用于后台消息 (例如天气或者位置信息)。最低优先级通知将只在状态栏显示图标,只有用户下拉通知抽屉才能看到内容。
常用方法的简单介绍
(1)setDefault(int defaults) 此方法的功能:向通知添加声音、闪灯和振动效果的最简单、使用默认(defaults)属性,也可以组合多个属性。
其对应属性包括:
Notification.DEFAULT_VIBRATE: 添加默认震动提醒
Notification.DEFAULT_SOUND: 添加默认声音提醒
Notification.DEFAULT_LIGHTS: 添加默认三色灯提醒(需要相关的硬件支持)
Notification.DEFAULT_ALL: 添加默认以上3种全部提醒
注意:添加震动时,需要添加相应的权限:
(2)简单介绍一下Flags:提醒标志符,向通知添加声音、闪灯和振动效果等设置达到通知提醒效果,可以组合多个属性
其中成员包括:
Notification.FLAG_SHOW_LIGHTS:三色灯提醒,在使用三色灯提醒时候必须加该标志符
Notification.FLAG_ONGOING_EVENT:发起正在运行事件,在活动中
Notification.FLAG_INSISTENT:让声音、振动无限循环,直到用户响应 ,取消或者打开
Notification.FLAG_ONLY_ALERT_ONCE:发起Notification后,铃声和震动均只执行一次
Notification.FLAG_AUTO_CANCEL:用户单击通知后自动消失
Notification.FLAG_NO_CLEAR:只有全部清除时,Notification才会清除 ,不清楚该通知,QQ的通知无法清除,就是用的这个
Notification.FLAG_FOREGROUND_SERVICE:表示正在运行的服务
具体代码如下:
@TargetApi(Build.VERSION_CODES.O)
private void sendSubscriMsg() {
String channelId = "1";//消息通道的ID,以后可以通过该ID找到该消息通道
String channelName = "订阅消息";//消息通道的名字
Intent intent = new Intent(this, MainActivity.class);
int flag = PendingIntent.FLAG_UPDATE_CURRENT;
PendingIntent contentIntent = PendingIntent.getActivity(this, 3, intent, flag);
//新建一个消息通道
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH);
//获取系统提供的通知管理服务
NotificationManager manager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
Notification notification = new Notification.Builder(this)
.setContentIntent(contentIntent)//设定点击通知之后启动的内容
.setContentTitle("收到一条订阅消息")//创建通知的标题
.setContentText("地铁沿线30万商铺抢购中!")//创建通知的内容
.setWhen(System.currentTimeMillis())//设定通知栏显示的时间
.setSmallIcon(R.drawable.ic_launcher_background)//创建通知的小图标
//使用系统默认的震动参数,会与自定义的冲突
.setDefaults(Notification.DEFAULT_ALL)
.setVibrate(new long[]{0, 100, 500, 700})
.setTicker("测试通知来了")
.setPriority(Notification.PRIORITY_DEFAULT)//设置通知栏的优先等级
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))//创建通知栏大图标
.setContent(getRemoteViews())//自定义通知栏的布局
.setAutoCancel(true)//设定点击通知之后通知是否消失
.setChannelId("1")//设置通道
.build();
//发送通知请求
manager.notify(2, notification);
}
public PendingIntent getDefaultIntent(int flags) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("cmd", flags);
int flag = PendingIntent.FLAG_UPDATE_CURRENT;
PendingIntent pendingInt = PendingIntent.getActivity(this, 1, new Intent(), flag);
return pendingInt;
}
由于我在代码中已经写了详细的注释,我就不对每个属性再做阐述,只对一些我认为,比较重点知识做一下讲解,如有其他问题请在下方给我评论,或者联系我([email protected])进行详细的探讨。
自定义通知栏的布局,需要使用RemoteViews类,此类在自定义视图布局文件中支持FrameLayout、LinearLayout、RelativeLayout三种布局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper这些控件,但是不支持其子类或者其他的安卓控件,如果有使用这些范围以外的控件,怎会报ClassNotFoundException异常。
具体代码如下:
//自定义通知栏布局
public RemoteViews getRemoteViews() {
Calendar calendar=Calendar.getInstance();
//获取系统时间
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
//构建字符串
StringBuilder s=new StringBuilder();
s.append(hour).append(":").append(minute).append(":").append(second);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_layout);
remoteViews.setTextViewText(R.id.tv_weather_case, "今天天气晴,温度10℃,请注意保暖 " + s);
remoteViews.setImageViewResource(R.id.iv_notification_icon, R.drawable.weather);
remoteViews.setOnClickPendingIntent(R.id.ll_Notification_Weather, getDefaultIntent(3));
return remoteViews;
}
这两段代码我写的也比较简单,没有再添加任何其他的功能,希望大家能认真看一下我写的代码,就能实现一个通知的功能,如果有什么问题,或者认为我代码有什么问题的及时联系我([email protected])