简介
Notification,是一种具有全局效果的通知,可以在系统的通知栏中显示。当 APP 向系> 统发出通知时,它将先以图标的形式显示在通知栏中。用户可以下拉通知栏查看通知的详细> > 信息。通知栏和抽屉式通知栏均是由系统控制,用户可以随时查看。
PendingIntent
pendingIntent是一种特殊的Intent。pendingIntent:等待、未决定的Intent。
主要的区别在于Intent的执行立刻的,而pendingIntent的执行不是立刻的。pendingIntent执行的操作实质上是参数传进来的Intent的操作,但是使用pendingIntent的目的在于只有满足条件才能执行它所包含的Intent操作。
主要使用范围:Notificatio,短消息发送和警报器执行等等。
获取PendingIntent方式:
//获取一个用于启动 Activity 的 PendingIntent 对象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);
//获取一个用于启动 Service 的 PendingIntent 对象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);
//获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
PendingIntent具有以下几种flag:
- FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,然后重新生成一个 PendingIntent 对象。
- FLAG_IMMUTABLE:创建的PendingIntent不可变,API23加入。
- FLAG_NO_CREATE:如果当前系统中不存在相同的 PendingIntent 对象,系统将不会创建该 PendingIntent 对象而是直接返回 null 。
- FLAG_ONE_SHOT:该 PendingIntent 只作用一次。
- FLAG_UPDATE_CURRENT:如果系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,但是会使用新的 Intent 来更新之前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras。
普通Notification
发送Notification的步骤:
- 获取NotificationManager实例;
- 实例化Notification.Builder并设置相关属性(Android3.0以上);
- 通过 builder.build() 方法生成 Notification 对象;
- 通过NotificationManager实例发送通知。
代码实现:
public void sendNotification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("普通通知")
.setContentText("这是普通通知内容")
.setAutoCancel(true)
.build();
manager.notify(1, notification);
}
利用PendingIntent给Notification设置 Action:
public void common_notification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.mrsorrow.xin")), PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("普通通知")
.setContentText("这是普通通知内容")
.setAutoCancel(true) //点完消失
.setContentIntent(intent)
.build();
manager.notify(2, notification);
}
更新通知:
更新通知只需要再次发送相同 ID 的通知即可,如果之前的通知还未被取消,则会直接更新该通知相关的属性;如果之前的通知已经被取消,则会重新创建一个新通知。
取消通知:
共四种方式:
- 设置了setAutoCancel()或FLAG_AUTO_CANCEL的通知,点击该通知时会清除它;
- 通过NotificationManager调用cancel(int id)方法清除指定 ID 的通知;
- 通过NotificationManager调用 cancel(String tag, int id) 方法清除指定 TAG和ID的通知;
- 通过NotificationManager调用cancelAll()方法清除所有该应用之前发送的通知。
如果你是通过 NotificationManager.notify(String tag, int id, Notification notify) 方法创建的通知,那么只能通过 NotificationManager.cancel(String tag, int id) 方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。
设置Notification的通知效果
设置铃声:
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("普通通知")
.setContentText("这是普通通知内容")
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_SOUND) //默认铃声
.build();
设置震动:
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("普通通知")
.setContentText("这是普通通知内容")
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_VIBRATE)
.build();
设置呼吸灯:
(这里无效,原因未知。小米4C,MIUI8,怀疑被拦截...)
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("普通通知")
.setContentText("这是普通通知内容")
.setAutoCancel(true)
.setContentIntent(intent)
.setLights(0x7788aa, 3000, 3000)
//.setDefaults(Notification.DEFAULT_ALL)
.build();
折叠式Notification
折叠式Notification是一种自定义视图的Notification,用来显示长文本和一些自定义的布局的场景。它有两种状态,一种是普通状态下的视图(如果不是自定义的话和上面普通通知的视图样式一样),一种是展开状态下的视图。和普通Notification不同的是,我们需要自定义的视图,而这个视图显示的进程和我们创建视图的进程不再一个进程,所以我们需要使用RemoteViews。
发送折叠式通知代码:
public void fold_notification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.mrsorrow.xin")), PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("折叠通知")
.setContentText("这是折叠通知内容")
.setAutoCancel(true)
.setContentIntent(intent)
.setDefaults(Notification.DEFAULT_VIBRATE)
.build();
notification.bigContentView = new RemoteViews(getPackageName(), R.layout.notification_fold);
manager.notify(2, notification);
}
自定义视图布局:
悬挂式Notification
悬挂式Notification是android5.0新增加的方式,和前两种显示方式不同的是,前两种需要下拉通知栏才能看到通知,而 悬挂式Notification不需要下拉通知栏就直接显示出来悬挂在屏幕上方并且焦点不变仍在用户操作的界面因此不会打断用户的操作,过几秒就会自动消失。
调用setFullScreenIntent来将Notification变为悬挂式Notification:
public void hang_notification(View view) {
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.mrsorrow.xin")), PendingIntent.FLAG_CANCEL_CURRENT);
Intent hangIntent = new Intent();
hangIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
hangIntent.setClass(this, MainActivity.class);
PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, hangIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("悬挂通知")
.setContentText("这是悬挂通知内容")
.setContentIntent(intent)
.setAutoCancel(true)
.setLights(0x7788aa, 3000, 3000)
.setFullScreenIntent(hangPendingIntent, true)
.build();
manager.notify(2, notification);
}
Notification的显示等级
Notification的显示等级共三种:
- VISIBILITY_PUBLIC:任何情况都会显示通知
- VISIBILITY_PRIVATE:只有在没有锁屏时会显示通知
- VISIBILITY_SECRET:在pin、password等安全锁和没有锁屏的情况下才能够显示
调用setVisibility方法设置等级:
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
参考
- 刘望舒 << Android进阶之光 >>
- Android Notification 详解