android 特殊用户通知用法汇总--Notification源码分析
一直用的android手机,用过这么多的app,平时也会遇到有趣的通知提醒,在这里先总结两种吧,notification和图标数字,有的以后看到再研究。还有,推广一下哈,刚刚建立一个Q群544645972,有兴趣的加一下,一起成长。
动态改变
将一个notification的setOngoing属性设置为true之后,notification就能够一直停留在系统的通知栏直到cancel或者应用退出。所以有的时候需要实时去根据情景动态改变notification,这里以一个定时器的功能为例,需要每隔1s去更新一下notification,具体效果:
非常简单的功能,代码也很简单:
<CODE class="hljs java">private Timer timer; private TimerTask task; ... if (timer != null) return; timer = new Timer("time"); task = new TimerTask() { @Override public void run() { showDynamicNotification(); } }; timer.scheduleAtFixedRate(task, 0, 1000); private void showDynamicNotification() { L.i("show dynamic notification"); mBuilder = new NotificationCompat.Builder(NotificationActivity.this); RemoteViews view = new RemoteViews(getPackageName(), R.layout.layout_notification); view.setTextViewText(R.id.tv_number, parseDate()); view.setImageViewResource(R.id.iv_icon, R.mipmap.ic_launcher); Intent intent = new Intent(NOTIFY_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(NotificationActivity.this, 1000, intent, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(pendingIntent) .setTicker("you got a new message") .setOngoing(true) .setContent(view); notification = mBuilder.build(); notificationManager.notify(NOTIFY_ID2, notification); } private String parseDate() { SimpleDateFormat format = new SimpleDateFormat("yyyy hh:mm:ss", Locale.getDefault()); return format.format(System.currentTimeMillis()); }</CODE>
需要注意的是Notification.Builder 是 Android 3.0 (API 11) 引入的,为了兼容低版本,我们一般使用 Support V4 包提供的 NotificationCompat.Builder 来构建 Notification。要想动态更新notification,需要利用 NotificationManager.notify() 的 id 参数,该 id 在应用内需要唯一(如果不唯一,在有些4.x的手机上会出现pendingIntent无法响应的问题,在红米手机上出现过类似情况),要想更新特定 id 的通知,只需要创建新的 notification,并触发与之前所用 id 相同的 notification,如果之前的通知仍然可见,则系统会根据新notification 对象的内容更新该通知,相反,如果之前的通知已被清除,系统则会创建一个新通知。
在这个例子中使用的是完全自定义的remoteViews,remoteViews和普通view的更新机制不一样,网上资料很多,感兴趣的可以去仔细了解。还有一个就是PendingIntent,这就不详细介绍了,这里简单列一下PendingIntent的4个flag的作用
big view
Notification有两种视觉风格,一种是标准视图(Normal view)、一种是大视图(Big view)。标准视图在Android中各版本是通用的,但是对于大视图而言,仅支持Android4.1+的版本,比如邮件,音乐等软件就会使用到这种大视图样式的扩展通知栏,系统提供了setStyle()函数用来设置大视图模式,一般情况下有三种模式提供选择:
NotificationCompat.BigPictureStyle, 在细节部分显示一个256dp高度的位图NotificationCompat.BigTextStyle,在细节部分显示一个大的文本块。NotificationCompat.InboxStyle,在细节部分显示一段行文本。

的效果,基本和一些主流媒体播放器的界面类似了,在这就不具体介绍了,提供一篇资料:controllingMedia
如果不使用上面的几种style,完全自定义布局也是可以的,例如实现:

在这我就以一个简单的实现为例,效果如下:

代码:
RemoteViews smallView = new RemoteViews(getPackageName(), R.layout.layout_notification);
smallView.setTextViewText(R.id.tv_number, parseDate());
smallView.setImageViewResource(R.id.iv_icon, R.mipmap.ic_launcher);
mBuilder = new NotificationCompat.Builder(NotificationActivity.this);
mBuilder.setSmallIcon(R.mipmap.ic_launcher)
.setNumber((int) (Math.random() * 1000))
//No longer displayed in the status bar as of API 21.
.setTicker("you got a new message")
.setDefaults(Notification.DEFAULT_SOUND
| Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)
// .setDeleteIntent()
.setAutoCancel(true)
.setWhen(0)
.setPriority(NotificationCompat.PRIORITY_LOW);
intent = new Intent(NOTIFY_ACTION);
pendingIntent = PendingIntent.getBroadcast(NotificationActivity.this,
1000, intent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pendingIntent);
//在5.0版本之后,可以支持在锁屏界面显示notification
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
}
notification = mBuilder.build();
notification.contentView = smallView;
//如果系统版本 >= Android 4.1,设置大视图 RemoteViews
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
RemoteViews view = new RemoteViews(getPackageName(), R.layout.layout_big_notification);
view.setTextViewText(R.id.tv_name, "我是名字1我是名字2我是名字3我是名字4我是名字5我是名字6我是名字7我是名字");
view.setOnClickPendingIntent(R.id.btn_click_close,
PendingIntent.getBroadcast(NotificationActivity.this, 1001,
new Intent(CLICK_ACTION), PendingIntent.FLAG_UPDATE_CURRENT));
//textview marquee property is useless for bigContentView
notification.bigContentView = view;
}
notificationManager.notify(NOTIFY_ID3, notification);
xml布局:
<framelayout android:layout_height="150dp" android:layout_width="match_parent">