Notification可以让我们在获取消息的时候,在状态栏、锁屏界面来显示相应的信息。由于不同厂商对Notification做了深度定制,导致部分属性设置了没有效果;而且随着Android 版本的不断升级,不得不去解决Notification的兼容问题。

由于目前市场上手机的系统版本基本都在Android4.4以上,所以Android4.4之前版本就不需要考虑了。

参考文章:https://www.jianshu.com/p/cb8426620e74

一、Notification的创建

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进行分类。

二、介绍3种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");        }    }}

注册广播

                        

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 permissionNotification.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_LARGENotification.BADGE_ICON_SMALLNotification.BADGE_ICON_NONE

由于Android手机品牌众多,角标兼容问题也越来越多,需要做各种机型的适配。

更多相关文章

  1. 一统天下 Google着手Android多版本题目
  2. Android(安卓)APK升级代码编写心得
  3. Android中出现 Error:In declare-styleable FontFamilyFont, una
  4. Android(安卓)通过DownloadManager实现自动更新的demo
  5. Android(安卓)4.0新特性总结
  6. android 6.0(api 23) SDK,不再提供org.apache.http.*(只保留几个
  7. 【Android开发】交互界面布局详解
  8. 新版本的tlplayer for android ,TigerLeapMC for windows发布了
  9. Android面试系列文章2018之Android(安卓)Studio目录结构篇

随机推荐

  1. 打造开发神器—Android(安卓)Studio上的
  2. android OpenGLES开发 第五课 纹理映射
  3. Android(安卓)ApiDemos示例解析(11):App->
  4. Android-DialogFragment快速指南
  5. Android(安卓)Camera中无法回调PictureCa
  6. android linux 休眠 深度睡眠 查看 方法
  7. Android中如何获取IMEI号码
  8. Android(安卓)sendToTarget
  9. android 中文 api (72) ―― BluetoothSock
  10. Activity伪造Dialog的时候不能全屏显示