一般结合一些透传消息(比如:个推推送),有时客户端需要自己生成相关需求的通知栏,生成的通知栏并且点击后,可以跳转到指定页面并携带上所需的参数。
private static void showNotification(Context context, String contentTitle, String contentText, PendingIntent intent) {
int channelId = new Random().nextInt(543254);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, String.valueOf(channelId));
builder.setContentTitle(contentTitle)
.setContentText(contentText)
.setContentIntent(intent)
.setTicker("")//通知首次出现在通知栏,带上升动画效果的
.setPriority(Notification.PRIORITY_DEFAULT)//设置该通知优先级
.setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
.setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
.setDefaults(Notification.DEFAULT_VIBRATE);//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = "yourname";
NotificationChannel mChannel = new NotificationChannel(String.valueOf(channelId), name, NotificationManager.IMPORTANCE_HIGH);
if (notificationManager != null) {
notificationManager.createNotificationChannel(mChannel);
builder.setChannelId(String.valueOf(channelId));
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setSmallIcon(R.drawable.ic_notification); //需要使用背景透明,图标为纯白色的图标。不然在很多机型上,如果直接使用应用icon,会直接显示纯白色图标,体验会不好。
} else {
builder.setSmallIcon(R.mipmap.ic_launcher);
}
if (notificationManager != null) {
notificationManager.notify(channelId * 10, builder.build());
}
}
//https://stackoverflow.com/questions/3168484/pendingintent-works-correctly-for-the-first-notification-but-incorrectly-for-the
private static PendingIntent getMainActivityIntent(Context context, String jumpPageType, int requestCode, String sourceId) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setAction(Long.toString(System.currentTimeMillis()));
intent.putExtra("jump_page_type", jumpPageType);
intent.putExtra("source_id", sourceId);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setComponent(new ComponentName(context, MainActivity.class));
// FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
return PendingIntent.getActivity(context, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
}
以上代码有用到 PendingIntent, 想对PendingIntent的内部机制有更多了解的,可以看下这篇文章:https://my.oschina.net/youranhongcha/blog/196933
PendingIntent.getActivity(Context context, int requestCode, Intent intent, int flags)
第一个参数连接上下文的context
第二个参数是对PendingIntent的描述,请求值不同Intent就不同
第三个参数是一个Intent对象,包含跳转目标
第四个参数有4种状态
FLAG_CANCEL_CURRENT:如果当前系统中已经存在一个相同的PendingIntent对象,那么就将先将已有的PendingIntent取消,然后重新生成一个PendingIntent对象。
FLAG_NO_CREATE:如果当前系统中不存在相同的PendingIntent对象,系统将不会创建该PendingIntent对象而是直接返回null。
FLAG_ONE_SHOT:该PendingIntent只作用一次。在该PendingIntent对象通过send()方法触发过后,PendingIntent将自动调用cancel()进行销毁,那么如果你再调用send()方法的话,系统将会返回一个SendIntentException。
FLAG_UPDATE_CURRENT:如果系统中有一个和你描述的PendingIntent对等的PendingInent,那么系统将使用该PendingIntent对象,但是会使用新的Intent来更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。
如果使用PendingIntent.FLAG_UPDATE_CURRENT,那么每次notifiId都是相同的数字,说明PendingIntent是一个,旧的参数被更新了。
如果使用PendingIntent.FLAG_ONE_SHOT,那么PendingIntent只是第一次有效,后来再点击别的Notification就无效了。