赞
踩
Notification可以让我们在获取消息的时候,在状态栏、锁屏界面来显示相应的信息。由于不同厂商对Notification做了深度定制,导致部分属性设置了没有效果;而且随着Android 版本的不断升级,不得不去解决Notification的兼容问题。
由于目前市场上手机的系统版本基本都在Android4.4以上,所以Android4.4之前版本就不需要考虑了。
参考文章:https://www.jianshu.com/p/cb8426620e74
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//Android4.1+ 谷歌推出了Notification.Builder(建造者模式)方式创建通知
//Notification.Builder builder = new Notification.Builder(this);
//Google后来推出了NotificationCompat.Builder方式,为各种配置做兼容性处理,不过一个参数的方法已过时,
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
builder.setSmallIcon(R.drawable.user);
manager.notify(1,builder.build());
这种builder只带一个参数的创建方式,提示已经过时,原因是升级到Android O 版本后,该方法被以下方法取代
NotificationCompat.Builder(Context context, String channelId)
即新增一个String参数即可,channelId的作用是将notification进行分类。
1、普通Notification
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default");
Intent normalIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,normalIntent,0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.small_icon);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.big_icon));
builder.setAutoCancel(true);
builder.setContentTitle("普通通知标题");
builder.setContentInfo("这是一条通知信息,请查收");
builder.setContentText("这是一条通知文本,请阅读");
manager.notify(1,builder.build());
2、折叠式Notification
这是一种自定义视图的Notification,用来显示长文本和一些自定义的布局场景。它有两种状态:一种是普通状态下的视图,一种是展开状态下的视图。和普通Notification不同的是,我们需要自定义视图,而这个视图显示的进程和我们创建视图的进程不在一个进程,所以需要使用RemoteViews。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "fold"); Intent mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/")); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mIntent, 0); builder.setContentIntent(pendingIntent); builder.setSmallIcon(R.drawable.small_icon); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_icon)); builder.setAutoCancel(true); builder.setContentTitle("折叠式通知标题"); builder.setContentInfo("这是一条通知信息,请查收"); builder.setContentText("这是一条通知文本,请阅读"); Notification notification = builder.build(); RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_fold); notification.contentView = remoteViews; notification.bigContentView = remoteViews; manager.notify(2, builder.build());
3、悬挂式Notification
这是Android5.0新增的方式。和前两种显示不同的是,前两种需要下拉通知栏才能看到通知,而悬挂式Notification不需要下拉通知栏就直接显示出来悬挂在屏幕上坟,并且焦点不变,仍在用户操作的界面,因此不会打断用户的操作,过几秒就会消失。它需要调用setFullScreenIntent来将Notification变为悬挂式。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "hang"); Intent hangIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.baidu.com/")); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, hangIntent, 0); builder.setContentIntent(pendingIntent); builder.setSmallIcon(R.drawable.small_icon); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.big_icon)); builder.setAutoCancel(true); builder.setContentTitle("悬挂式通知标题"); builder.setContentInfo("这是一条通知信息,请查收"); builder.setContentText("这是一条通知文本,请阅读"); //设置跳转 Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setClass(this, MyNotificationActivity.class); PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); builder.setFullScreenIntent(hangPendingIntent, true); manager.notify(3, builder.build());
三种通知在Android低版本上会有区别,但在Android9.0系统上测试都是以悬挂式展示的。
1、Android4.1之前的版本,创建Notification方式
Notification notification = new Notification();
2、Android5.0+的版本,创建Notification方式
Notification notification = new Notification.Builder(mContext).build();
3、Android6.0开始,创建Notification方式
Notification notification = new NotificationCompat.Builder(mContext).build();
4、Android8.0开始,创建Notification方式,需要制定channel属性
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("channel_id", "notice", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "channel_id");
//如果是通过new Notification.Builder(this)创建Notification,需要通过 .setChannelId("channel_id")属性设置channel
1、setSmallIcon设置小图标
setSmallIcon必须设置,否则通知不会显示
2、setContentTitle设置通知标题
3、setContentText设置通知内容
4、setContentIntent 点击通知要跳转的意图,需要用到PendingIntent
5、setAutoCancel 点击通知时是否自动消失,需要重点注意的是,setAutoCancel需要和setContentIntent一起使用,否则无效。
6、setDeleteIntent 左滑或者右滑通知时,删除通知。
一般有两种消失的行为:第一种是点击消失,第二种是滑动消失,可以通过广播监听这两种事件。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationCompat.Builder builder = neNotificationCompat.Builder(this,"delete") Intent clickIntent = neIntent(this,NotificationBroadcastReceiver.class); clickIntent.setAction("com.example.click"); PendingIntent clickPI PendingIntent.getBroadcast(this,1,clickIntent,PendingIntent.FLACANCEL_CURRENT) Intent cancelIntent = neIntent(this,NotificationBroadcastReceiver.class); cancelIntent.setAction("com.example.cancel"); PendingIntent cancelPI PendingIntent.getBroadcast(this,2,cancelIntent,PendingIntent.FL_CANCEL_CURRENT) builder.setSmallIcon(R.drawable.small_icon) .tContentTitle("我是通知的标题")//设置通知标题 .setContentText("我是一个通知")//设置通知内容 .setContentIntent(clickPI)/设置pendingIntent,点击通知时就会用到 .setAutoCancel(true)//设为true,点击通知栏移除通知 .setDeleteIntent(cancelPI);//设置pendingIntent,左滑右知时就会用到 manager.notify(0,builder.build());
//广播接收的类
public class NotificationBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (TextUtils.isEmpty(action)){ return; } if (action.equals("com.example.click")){ System.out.println("click"); } if (action.equals("com.example.cancel")){ System.out.println("cancel"); } } }
注册广播
<receiver android:name=".notification.NotificationBroadcastReceiver">
<intent-filter>
<action android:name="com.example.click"/>
<action android:name="com.example.cancel"/>
</intent-filter>
</receiver>
7、setLargeIcon 设置大图标
8、setNumber 显示在右边的数字 部分机型没有效果
9、setOngoing 是否是正在进行中的通知,默认是false,如果设置成true,左右滑动的时候就不会被删除了
10、setOnlyAlertOnce 设置是否只通知一次,默认值是false,如果设置成true,则只会通知一次。
11、setProgress 为通知设置设置一个进度条
setProgress(int max, int progress, boolean indeterminate)
max:最大值
progress:当前进度
indeterminate:进度是否确定
12、setStyle 为通知设置样式
1)BigPictureStyle 下拉通知完全展开时,会显示大图
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.bigPicture(BitmapFactory.decodeResource(getResoces(),R.drawable.loop));
bigPictureStyle.setBigContentTitle("大图标题");
bigPictureStyle.setSummaryText("这是大图样式内容"
//然后设置样式
builder.setStyle(bigPictureStyle);
2)BigTextStyle 感觉跟普通通知字体没什么区别
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
bigTextStyle.setBigContentTitle("标题");
bigTextStyle.setSummaryText("这是简要内容");
bigTextStyle.bigText("这是文本内容!!!");
//然后设置样式
builder.setStyle(bigTextStyle);
3)DecoratedCustomViewStyle 功能是自定义通知布局
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_fold);
builder.setCustomContentView(remoteViews);
//setCustomContentView也可以用下面两个替换
//setCustomBigContentView(remoteViews)//设置通知的布局
//setCustomHeadsUpContentView(remoteViews);//设置悬挂通知的布局
setSmallIcon的属性还是要设置的,不然接收不到通知
4)InboxStyle 添加行
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.addLine("第一行");
inboxStyle.addLine("第二行");
inboxStyle.addLine("第三行");
inboxStyle.addLine("第四行");
inboxStyle.addLine("第五行");
inboxStyle.addLine("第六行");
inboxStyle.addLine("第七行");
inboxStyle.addLine("第八行");
inboxStyle.addLine("第九行");
inboxStyle.setBigContentTitle("大标题");
inboxStyle.setSummaryText("内容");
//然后设置样式
builder.setStyle(inboxStyle);
5)MessagingStyle
NotificationCompat.MessagingStyle messagingStyle = new NotificationCompat.MessagingStyle("aaa");
NotificationCompat.MessagingStyle.Message message = new NotificationCompat.MessagingStyle.Message("测试",System.currentTimeMillis(),"发送人");
messagingStyle.addMessage(message);
messagingStyle.setConversationTitle("message标题");
13、setDefaults
向通知添加声音、闪灯和震动效果,最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,如果没有设置这个属性通知可能没有声音。
setDefaults(Notification.DEFAULT_ALL);
Notification.DEFAULT_VISIBLE //添加默认震动提醒 需要VIBRATE permission
Notification.DEFAULT_SOUND //添加默认声音提醒
Notification.DEFAULT_LIGHTS //添加默认三色灯提醒 有的机型可能不支持
Notification.DEFAULT_ALL //添加默认以上三种全部提醒
14、setVibrate 设置使用震动模式
setVibrate(new long[]{3000,1000,500,700,500,300});//延迟3秒,然后震动1000ms,再延迟500ms,接着震动700ms,最后再延迟500ms,接着震动300ms
如果setDefaults的属性设置的是Notification.DEFAULT_ALL或者Notification.DEFAULT_VISIBLE,setVibrate将无效,因为Notification.DEFAULT_ALL或者Notification.DEFAULT_VISIBLE会替代setVibrate。
15、setSubText
在通知上新增一行文本,使原本两行文本变成三行文本
16、setTicker 设置通知在第一次到达时在状态栏中显示的文本
有的机型不生效,用的华为Android4.4.2版本可以生效,Android9.0版本是以悬挂式通知显示的,也不会有效果
17、setUsesChronometer 设置是否显示时间计时,电话通知就会使用到。true 会计时 false 不会计时
18、setWhen 通知产生的时间,会在通知栏信息里显示,一般是系统获取到的时间
如果没有设置,默认是当前时间戳。
19、setShowWhen 设置是否显示当前时间 如果已经设置了setUsesChronometer(true),则当前时间就显示不了。
20、setExtras 为通知设置数据,在Android4.4新增了设置数据的入口。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//Android4.4以上
Bundle bundle = new Bundle();
builder.setExtras(bundle);
}
21、setGroup 通知分组,即在同一个应用程序下,如果超过4条通知,会自动把通知进行分组。主要体现在Android7.0以上的手机。
22、setGroupSummary 如果设为false,结合setGroup使用,会取消分组
23、setColor 设置通知栏颜色(Android5.0新增),测试部分机型没有效果,用Android9.0的系统只是把通知的图标改变了颜色。
24、setCategory 设置通知类别
//通知类别 public static final String CATEGORY_CALL = "call"; public static final String CATEGORY_MESSAGE = "msg"; public static final String CATEGORY_EMAIL = "email"; public static final String CATEGORY_EVENT = "event"; public static final String CATEGORY_PROMO = "promo"; public static final String CATEGORY_ALARM = "alarm"; public static final String CATEGORY_PROGRESS = "progress"; public static final String CATEGORY_SOCIAL = "social"; public static final String CATEGORY_ERROR = "err"; public static final String CATEGORY_TRANSPORT = "transport"; public static final String CATEGORY_SYSTEM = "sys"; public static final String CATEGORY_SERVICE = "service"; public static final String CATEGORY_REMINDER = "reminder"; public static final String CATEGORY_RECOMMENDATION = "recommendation"; public static final String CATEGORY_STATUS = "status";
25、setPublicVersion 设置安全锁屏下的通知
Android4.4.2的设备没有添加builder.setVisibility(Notification.VISIBILITY_PUBLIC);锁屏状态下也可以收到通知
26、setVisibility 设置通知的显示等级
//Android5.0之后新增
VISIBILITY_PUBLIC 任何情况都会显示通知
VISIBILITY_PRIVATE 只有在没有锁屏时会显示通知
VISIBILITY_SECRET 在安全锁和没有锁屏的情况下显示通知
27、addAction 添加内联回复的通知。支持Android7.0以上的手机
实现方式
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel("reply", "name", NotificationManager.IMPORTANCE_HIGH); manager.createNotificationChannel(channel); } NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "reply"); builder.setSmallIcon(R.drawable.small_icon); Intent intent = new Intent(this,NotificationBroadcastReceiver.class); intent.setAction("com.example.reply"); intent.putExtra("messageId", 1); PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setRemoteInputHistory(new String[]{"这条通知可以点击下面按钮直接回复"}); RemoteInput input = new RemoteInput.Builder("key_text_reply") .setLabel("回复") .build(); NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.small_icon,"点击直接回复",pendingIntent) .addRemoteInput(input) .build(); builder.addAction(action); manager.notify(6, builder.build());
在内联输入框中输入想要回复的文字,点击发送之后会收到一个广播,广播的处理如下:
int messageId = intent.getIntExtra("messageId", 0); Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); if (remoteInput != null) { NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); CharSequence message = remoteInput.getCharSequence("key_text_reply"); NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "6"); builder.setSmallIcon(R.drawable.small_icon) .setContentTitle("内联回复")//设置通知标题 .setContentText(message)//设置通知内容 .setAutoCancel(true);//设为true,点击通知栏移除通知 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Android 8.0以上 String channelID = "6"; String channelName = "通知测试"; NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_DEFAULT ); manager.createNotificationChannel(channel); //创建通知时指定channelID builder.setChannelId(channelID); } Notification notification = builder.build(); manager.notify(messageId, notification);
28、setSound 设置铃声
setSound(Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.publicnotify))
29、设置呼吸灯
setLights(Color.RED,2000,Color.BLUE)
参数依次是:灯光颜色,亮持续时间,暗的时间,不是所有颜色都可以,这跟设备有关,有些手机还不带三色灯;另外,还需要为Notification设置flags为Notification.FLAG_SHOW_LIGHTS才支持三色灯提醒!
30、setBadgeIconType 设置角标样式
Notification.BADGE_ICON_LARGE
Notification.BADGE_ICON_SMALL
Notification.BADGE_ICON_NONE
由于Android手机品牌众多,角标兼容问题也越来越多,需要做各种机型的适配。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。