一、 Notification 在以下场景中比较常见
(1) 短信,QQ,微信等消息的通知提醒(2) 后台服务的显示,比如网易云音乐,下载进度
(3) 客服端推送的消息,比如直播平台的飞机票,应用更新
其是一种比较方便的与用户交流方式。Notification为Android的重要组成部分,所以有其一套使用规则,下面根据代码进行讲解。
二、一般步骤
1. 创建NotificationManager 通知管理类,用来对消息的发送,取消等操作2. 创建建造者NotificationCompat.Builder (), 用来创建Notification对象,设置通知的相关内容
3. Notification 设置Flag 显示不同效果
4. 使用Notification 发送通知
注: 之前看资料看到很多博客有讲不设置SmallIcon,ContentTitle,ContentText会报错,由于Android 系统不同厂商进行定制,所以这边属于适配问题了,比如我现在这款华为手机3个都不设置也不会报错。单设置一个SmallIcon就能显示通知
ps: 由于不同版本创建的Builder 方式不同,所以在适配的时候需要注意。
1.先来看旧版,Api 11 之前,3.0 之前的用法
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.mipmap.ic_launcher, "This is bitch.", System.currentTimeMillis());
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
notification.setLatestEventInfo(this, "This is ContentTitle","This is ContentText", pi);
manager.notify(1, notification);
manager.cancel(1); // 清除通知栏上的内容,这里的 1 是通知的Id
2. 高于API Level 11,低于API Level 16 (Android 4.1.2)版本的系统
可使用Notification.Builder来构造函数。但要使用getNotification()来使notification实现。此时,前面版本在notification中设置的Flags,icon等属性都已经无效,要在builder里面设置。
Notification.Builder builder = new Notification.Builder(context)
.setAutoCancel(true)
.setContentTitle("title")
.setContentText("describe")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis())
.setOngoing(true);
notification=builder.getNotification();
3. 高于16 获得Notification 实例使用build()
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder nb = new Notification.Builder(this);
nb.setSmallIcon(R.drawable.fullscreen_seekbar_thumb_childmode);
nb.setContentTitle("ContentTitke");
nb.setContentText("ContentText");
notificationManager.notify(1, nb.build());
4. 本文使用v7 包中的,NotificationCompat.Builder
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder nbu = new NotificationCompat.Builder(this);
nbu.setSmallIcon(R.drawable.ic_launcher); //设置小图标 状态栏看到的图标
nbu.setContentTitle("ContentTitle"); //设置标题
nbu.setContentText("ContentText"); //设置内容
nbu.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.feedback_person)); //拉下通知栏显示的图标
nbu.setWhen(System.currentTimeMillis());
notificationManager.notify(id, nbu.build()); //发送通知,id用来判断notification是否是同一个,相同不重发。
三、参数含义
setSmallIcon //没拉下通知时的图标
setTicker //在状态栏情况下显示的信息
setContentTitle //标题setContentText //内容
setLargeIcon //下拉通知后展示的图标
setWhen //发送的时间
setContentInfo //时间下面的内容
setContentIntent //设置Intent
setSound //铃声
setVibrate //震动
setLights //呼吸灯
setCustomContentView //自定义view
setPriority //优先级
常用Flag
notification.flags |= Notification.FLAG_NO_CLEAR; //通知栏无法手动滑动或清除按钮删除,只有通过代码中cancel 清除
notification.flags |= Notification.FLAG_AUTO_CANCEL; //点击通知后,自动删除,前提设置Intent 否则没反应(或者手动滑动,清除按钮,cancel清除)
notification.flags |= Notification.FLAG_ONGOING_EVENT; //正在运行,不能手动删除,清除按钮删除,只有通过cancel 类似第一个
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("AAA", "收到");
long[] vibrate = new long[]{0, 500, 1000, 1500};
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder nbu = new NotificationCompat.Builder(this);
nbu.setSmallIcon(R.drawable.fullscreen_seekbar_thumb_childmode);
nbu.setContentTitle("ContentTitle");
nbu.setContentText(1 + "");
nbu.setContentInfo("Con");
nbu.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.feedback_person));
nbu.setWhen(System.currentTimeMillis());
nbu.setContentIntent(pendingIntent); //添加意图,这边是点击后会跳转到MainActivity
// nbu.setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.rae)); //设置铃声
// nbu.setVibrate(vibrate); //1 设置震动,前提手机没开静音
// nbu.setLights(0xFF0000, 3000, 3000); //设置呼吸灯 由于手机厂商原因设置无效
Notification notification = nbu.build();
//调用系统默认铃声
//notify.defaults = Notification.DEFAULT_SOUND;
//调用自己提供的铃声
//notify.sound = Uri.parse("android.resource://com.littlejie.notification/"+R.raw.sound);
//调用系统自带的铃声
//notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
// notification.vibrate = vibrate; //2. 设置震动 过时的
//只有在设置了标志符Flags为Notification.FLAG_SHOW_LIGHTS的时候,才支持呼吸灯提醒。
//notification.flags = Notification.FLAG_SHOW_LIGHTS;
//设置lights参数的另一种方式
//notification.ledARGB = 0xFF0000;
//notification.ledOnMS = 500;
//notification.ledOffMS = 5000;
// notification.flags |= Notification.FLAG_NO_CLEAR; //通知栏无法手动滑动或清除按钮删除,只有通过代码中cancel 清除
// notification.flags |= Notification.FLAG_AUTO_CANCEL; //点击通知后,自动删除,前提设置Intent 否则没反应(或者手动滑动,清除按钮,cancel清除)
// notification.flags |= Notification.FLAG_ONGOING_EVENT; //正在运行,不能手动删除,清除按钮删除,只有通过cancel 类似第一个
notificationManager.notify(1, notification);
运行结果如下:
四、 PendingIntent
PendingIntent支持三种待定的意图:启动Activity,启动Service和发送Broadcast。对应于它的三个接口方法。
static PendingIntent
getActivity(Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.startActivity(Intent)
static PendingIntent
getService (Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.startService (Intent)
static PendingIntent
getBroadcast(Context context,int requestCode,Intent intent,int flags)
获取一个PendingIntent,该意图发生时,相当于Context.sendBroadcast(Intent)
其中context和intent不需要讲,主要说一下requestCode和flags。其中requestCode是PendingIntent发送发的请求码,多数情况下设置为0即可,requestCode会影响到flags的效果。
PendingIntent相同:Intent相同且requestCode也相同。(Intent相同需要ComponentName和intent-filter相同)
flags的常见类型有:
FLAG_ONE_SHOT:只能被使用一次,然后就会被自动cancel,如果后续还有相同的PendingIntent。那么他们的send方法就会调用失败。
FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统不会创建该PendingIntent对象,而是直接返回null。(很少使用)
FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。
FLAG_UPDATE_CURRENT:当前描述的PendingIntent如果已经存在,那么它们会被更新,即Intent中的Extras会被替换到最新的。
使用场景,音乐后台播放的控制台,是根据Service进行判断的。
五、 如何更新、取消Notification
在上面代码中会看到使用notify 发送通知,其参数其实有2种形式
public void notify(int id, Notification notification) {
throw new RuntimeException("Stub!");
}
public void notify(String tag, int id, Notification notification) {
throw new RuntimeException("Stub!");
}
第一个方法只设置id
第二个方法设置tag 以及 id
这2个不冲突,就算id相同。
这里的所谓更新,就是发送id相同或者tag+id相同的通知过去。
取消:
public void cancel(int id) //根据id 取消通知,不会影响下面的
public void cancel(String tag, int id) //根据tag,id取消通知
public void cancelAll() //取消该Notification Manager所有的通知
六、使用自定义布局
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder nbuilder = new NotificationCompat.Builder(this);
nbuilder.setSmallIcon(R.drawable.ic_launcher);
nbuilder.setWhen(System.currentTimeMillis());
remoteViews = new RemoteViews(getPackageName(), R.layout.my_notification); //提供包名,以及需要加载的布局
remoteViews.setOnClickPendingIntent(R.id.openActivity, pendingIntent); //给某个控件添加点击事件
nbuilder.setCustomContentView(remoteViews); //将布局设置进去
notifi = nbuilder.build();
notificationManager.notify(3, notifi);
效果图如下:
另外常用的方法如下,都是使用viewId进行操作
- setTextViewText(viewId, text) 设置文本
- setTextColor(viewId, color) 设置文本颜色
- setTextViewTextSize(viewId, units, size) 设置文本大小
- setImageViewBitmap(viewId, bitmap) 设置图片
- setImageViewResource(viewId, srcId) 根据图片资源设置图片
- setViewPadding(viewId, left, top, right, bottom) 设置Padding间距
- setOnClickPendingIntent(viewId, pendingIntent) 设置点击事件
展示2个视图一个普通setCustomContentView,一个展开视图setCustomBigContentView
nbuilder.setCustomContentView(remoteViews); //将布局设置进去 nbuilder.setCustomBigContentView(new RemoteViews(getPackageName(), R.layout.big_notif));效果图如下:
setCustomContentView
setCustomBigContentView