Android 消息通知栏用法详解(二) 适配8.0

通知(Notification) 是Android 系统比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息的时,而该应用程序又处于后台,就可以借助通知来实现。比如微信弹窗。通过这篇文章,我们将学习到

  • Notification 的基本用法
  • Notification 声音、优先级、多文字和大图片的显示
  • Notification 高级玩法
  • 自定义 Notification 的布局

官网 Nitification 资料

一、基本用法

通知可以在 广播、activity 或者 service 去创建,不过在 activity 创建得比较少,一般都是应用在后台了,才需要去弄,不过我们是demo,所以写哪都没关系。

创建通知的基本步骤如下:

  1. 使用getSystemService 拿到 NotificationManager 的管理类
  2. 使用NotificationCompat 设置标题、内容、图片等
  3. 最后调用 NotificationManager 的 notify() 调出通知栏

上面中,为什么要使用 NotificationCompat 呢,因为Android系统的每一个版本都会对通知这部分功能进行或多或少的修改,API 比较不稳定,所以这里使用 v4 的包去兼容,当然,如果你使用 androidx,也就没啥问题了。
所以,一个简单的通知实例如下 :

以下代码建议在8.0之下运行,8.0以上,请参考下一篇文章

首先创建 NotificationManager

mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
 mBuilder = new NotificationCompat.Builder(this).setContentTitle("这是标题").setContentText("我是内容,我是demo").setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));//通过 builder.build() 拿到 notificationmNotificationManager.notify(1, mBuilder.build());

解释如下:

  • setContentTitle 为设置标题
  • setContentText 为正文内容
  • setWhen 为通知创建时间,以 ms 为单位
  • setSmallIcon 通知的小图标,注意只能使用 纯 alpha 图层的图片进行设置
  • setLargeIcon 通知栏的大图标

都设置完成之后,只要使用 nofity() 即可,其中,第一个参数为 id,后面用来取消通知的。所以随便填一个数字即可,效果如下。

可以看到,小图标是灰色的。当然了,google 要求是 alpha 的图层呢。
什么是 纯 alpha 的图层图片呢?通俗来讲,就是图片不要带颜色就可以了,当然UI设计师肯定知道,就是用 alpha 层去绘制图片吗,咱们也可以从 阿里巴巴的图片库下载,比如:

然后咱们设置一下

但是,发现默认还是灰色的,这里可以使用 setcolor 去设置:

 .setColor(getResources().getColor(R.color.colorPrimary))


这里咱们就设置好了小图标了

1.1 设置点击事件

一般的通知栏都是可以点击的,但是我们点击了一下,发现并没有什么用。当然,我们都没设置点击事件。
notification 的点击事件,可以通过设置 setContentIntent 来实现。它需要传递一个 PendingIntent。从而实现点击之后的跳转意图。
PendingIntent 的用法也很简单,它可以通过 getActivity(),getBroadcast() 和 getService() 来获取不同的实例,一个简单获取 activity 的方法如下:

Intent intent = new Intent(this,SecondActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_CANCEL_CURRENT);

它的参数也比较简单,第一个为 context,第二个为 requestCode,一般用不到,intent 即你要跳转的意图。第四个参数有5种选择,分别如下:

  • 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。

一般第四个传输,传递 0 或者FLAG_CANCEL_CURRENT 都可以。
所以,我们的通知代码改一下:

        mBuilder = new NotificationCompat.Builder(this).setContentTitle("这是标题").setContentText("我是内容,我是demo").setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)).setContentIntent(pi);//通过 builder.build() 拿到 notificationmNotificationManager.notify(1, mBuilder.build());

1.2 取消通知

点击之后,发现确实跳转了,但是通知栏还在。取消共有两种方式

  1. setAutoCancel(true) 在builder 那里,添加自动取消的功能
  2. mNotificationManager.cancel(1); 通过取消 id 取消,如果有 tag ,也可以使用 cancel(tag,id) 来取消

1.3 通知更新

更新通知,只需要重新 notify 相同的 id 即可,如果通知栏还在,则更新内容,如果不存在,则增加一个新的通知栏,如下,我们更新一下内容:

 mBuilder.setContentText("我更新了内容");mNotificationManager.notify(1,mBuilder.build());

二、通知栏效果

上面,咱们只是简单的实现了通知栏,但是一些好玩的效果,咱们并没有实现,这节,一起来看看通知栏的效果。

(请用真机测试)

2.1 声音

很多通知栏,都有声音的效果,同样,我们也可以设置。使用 setSound 即可实现,比如:

mBuilder = new NotificationCompat.Builder(this)...//这个看各自的手机的铃声的路径.setSound(Uri.fromFile(new File("system/media/audio/notifications/Argon.ogg"))).setAutoCancel(true);

除了自定义,还可以使用默认铃声:

.setDefaults(NotificationCompat.DEFAULT_SOUND)

2.2 震动

除了声音,还可以让手机震动,使用的是 setVibrate,它的参数为一个 long 的数组,以 ms 为单位,如果我们想让手机震动1s,延时一秒,再震动一次,当然,它需要向申请权限

<uses-permission android:name="android.permission.VIBRATE"/>
.setVibrate(new long[]{0,1000,1000,1000})

同理,也可以使用默认震动效果:

.setDefaults(NotificationCompat.DEFAULT_VIBRATE)

2.3 LED灯

现在手机都LED灯,在手机息屏或者未接来电灯,还是还有必要的。同样,可以使用 setLights() 来实现效果。它又三个参数,第一个是设置灯的颜色,第二个是灯亮的时间,第三个则是灯暗的时间。如下:

.setLights(Color.RED,1000,1000)

同理,用默认的

.setDefaults(NotificationCompat.DEFAULT_LIGHTS)

ps:在国内百花齐放的环境中,上面那玩意基本无效,只能看各自的厂商的说明文档去适配了。

如果你觉得,上面的设置太麻烦,还有一个方法,直接全部设置成默认的:

.setDefaults(NotificationCompat.DEFAULT_ALL)

三、Notification 的高级玩法

在实际应用中,我们常常需要配合一下实际场所来灵活应用通知栏。比如长文字,打图片、回复信息、或者跳转等。下面一起来学习。

3.1 优先级

优先级在 7.1 及以下有用,8.0 则使用 channel 来设置。
通知栏是可以设置优先级的,它有5个常亮可以选

  • PRIORITY_DEFAULT 默认优先级
  • PRIORITY_MIN 优先级最低,某个特定场合才显示
  • PRIORITY_LOW 优先级较低,系统可能将这类通知缩小,或者改变它的显示位置,比如靠后的位置
  • PRIORITY_HIGH 表示较高程度,系统可能对它进行方法,或者改变位置,比如靠前的位置
  • PRIORITY_MAX 优先级最高,这类通知会让用户立刻看到

比如,我们设置了 PRIORITY_MAX ,直接回显示出通知栏的效果:

3.2 setStyle 展开式通知

很多时候,我们想显示一段比较长的文字,或者一个比较大的图片,使用默认的 setContentText 或者 setLargeIcon 是不行的,但是可以使用 setStyle ,setStyle 可以让通知栏变大来显示通知。

3.2.1 长文字

比如,显示一段长文字:

.setStyle(new NotificationCompat.BigTextStyle().bigText("我是内容,我是demo\n我不是测试\n 我是长文字啊"))

效果如下:

3.2.2 大图片

设置一张图片:

  .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.update_app_top_bg)).setStyle(new NotificationCompat.BigPictureStyle().bigPicture(BitmapFactory.decodeResource(getResources(),R.mipmap.update_app_top_bg)).bigLargeIcon(null))

3.3 添加按钮

一个通知最多可以提供三个操作按钮,然该用户可以快速响应,比如暂停,上一曲下一曲这些常用的按钮,这里,可以通过 addAction 去编写,并把 PendingIntent 关联进去,比如广播:

mBuilder = new NotificationCompat.Builder(this).......addAction(R.mipmap.enter,"上一曲",pi).addAction(R.mipmap.enter,"开始",pi).addAction(R.mipmap.enter,"下一曲",pi);

效果如下:

3.4 添加回复操作

google 在 Android 7.0 (API 24) 中引入允许用户直接回复的的组件,使用 RemoeInput 设置好key,并把它交给 action,即可实现。先看效果

首先,创建 RemoteInput.Builder() 的实例,并设置好 key 值,这个后面在 intent 会拿到。
然后,创建 PendingIntent,为了方便实验,添加一个广播
最后,创建 Action,把 remoteInput 和 pendingIntent 穿进去,代码如下:

 private NotificationCompat.Action getRemoveAction(){//添加一个回复组件,RemoteInput remoteInput = new RemoteInput.Builder(REPLY_KEY).build();//添加一个 pendingIntent 的广播PendingIntent replyPi = PendingIntent.getBroadcast(this,2,new Intent("com.zhengsr.test"),PendingIntent.FLAG_UPDATE_CURRENT);//构建 actionNotificationCompat.Action action = new NotificationCompat.Action.Builder(R.mipmap.enter,"回复",replyPi).addRemoteInput(remoteInput).build();return action;}

然后直接添加 action 即可:

        mBuilder = new NotificationCompat.Builder(this).....addAction(getRemoveAction());

3.4.1 拿到回复内容

如果想要拿到用户的输入内容,则可以调用 RemoteInput.getResultsFromIntent(intent) ,即可拿到 Bundle 并拿到数据,如:

    class  MyBroadcastReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {Bundle bundle = RemoteInput.getResultsFromIntent(intent);if (bundle != null) {String replay = bundle.getString(REPLY_KEY);Log.d(TAG, "zsr onReceive: "+replay);}}}


同样,也可以使用 NotificationCompat.MessagingStyle 去专门传递消息。具体参考官方资料。

3.5 显示进度条

通知栏还可以显示进度条,在 builder 中使用 setProgress。

setProgress(int max, int progress, boolean indeterminate)

参数都能看得明白。比如,当我们开始的进度条,可以设置为:

setProgress(100,0,false)

更新的话,直接改变 progress 即可,如果想要取消,则 setProgress(0,0,false)就可

3.6 显示紧急通知

在某些情况下,就算屏幕锁屏了,一些通知还是要显示的,比如电话,闹钟等。当然,通知栏也支持,根据设备的情况,会分两种情况

  • 设备锁定 : 如果设备锁定了,则显示全屏的 Acitivyt,直接覆盖全屏
  • 设备为锁定: 则还是以通知栏的形式出现

可以通过设置 setFullScreenIntent(PendingIntent intent ,boolean highPriority) 来设置,如:

        mBuilder = new NotificationCompat.Builder(this).setContentTitle("紧急通知").setContentText("这是一条紧急通知").setWhen(System.currentTimeMillis())...setFullScreenIntent(pi,true)

其中 pi 为你要跳转的 PendingIntent。除了默认的情况,还可以通过设置 setVisibility(int visibility) 来设置锁屏屏幕的范围,共有三种选择:

  • VISIBILITY_PUBLIC 显示通知的完整内容。
  • VISIBILITY_SECRET 不在锁定屏幕上显示该通知的任何部分。
  • VISIBILITY_PRIVATE 显示基本信息,例如通知图标和内容标题,但隐藏通知的完整内容。你如,显示"您有三条新短信",但是发件人和内容不可见。

四、自定义布局

一般情况下,系统的通知,并不能满足我们的需求,且为了保证每个版本的样式统一。都会采用自定义布局的形式。
需要注意的是。在创建自定义布局的时候,我们需要提供两个 layout,一个收起的视图,它的高度上限为 64dp。一个是展开之后,它的上限为 256dp

4.1 为内容区域创建自定义布局

一般的自定义布局中,我们可以借助通用模板去构建一个基本布局,即保留时间戳,通知图标等装饰,而自定义由标题和文本内容的区域。
这个时候,可以使用 NotificationCompat.DecoratedCustomViewStyle 设置到 style 中,一般步骤如下:

  1. 构建基本通知,使用NotificationCompat.Builder
  2. 调用 setStyle().想其传递 NotificationCompat.DecoratedCustomViewStyle 实例
  3. 将其自定义布局扩展为 RemoveteViews 实例
  4. 调用 setCustomContentView 设置收起的通知布局
  5. 调用 setCustomBigContentView 设置扩展的通知布局

如果为多媒体播放控件创建自定义通知。可以使用NotificationCompat.DecoratedMediaCustomViewStyle 类

例如:

RemoteViews cusRemoveView = new RemoteViews(getPackageName(),R.layout.cus_notify_small);RemoteViews cusRemoveExpandView = new RemoteViews(getPackageName(),R.layout.cus_notify_large);mBuilder = new NotificationCompat.Builder(this).setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setStyle(new NotificationCompat.DecoratedCustomViewStyle()).setCustomContentView(cusRemoveView).setCustomBigContentView(cusRemoveExpandView);

其中,当我们在自定义布局时,通知的背景颜色可能因为版本而异,如果要跟随系统,在设置 TextView 控件时,可以使用 TextAppearance_Compat_Notification 样式,比如标题的TextAppearance_Compat_Notification_Title。 这样就能保证在不同版本中,textview 始终是正常显示的。比如 R.layout_cus_notify_small:

注意,目前layout只支持 LinearLayout、FrameLayout、RelativeLayout三种基本布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="64dp"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"style="@style/TextAppearance.Compat.Notification.Title"android:text="我是标题"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"style="@style/TextAppearance.Compat.Notification.Info"android:text="我是内容"/></LinearLayout>

而,R.layout_cus_notify_large 中,给其中一个 TextView设置红色,不设置 style,看看效果:


避免在 RemoteViews 上设置背景颜色,可能会导致文办颜色无法读取的问题

4.2 创建完全的自定义通知背景

如果你不想用系统的时间戳,通知图标等。可以去掉 setStyle(),只添加 setCustomContentView 和 setCustomBigContentView 即可。

要支持低于 Android 4.1(API 级别 16)的 Android 版本,您还应调用 setContent(),向其传递同一 RemoteViews 对象。

如需获取更多使用通知的示例代码,请参阅 Android 通知示例。

Android 消息通知栏用法详解(一)相关推荐

  1. android默认exported_Android android:exported = true 用法详解

    Android android:exported = true 用法详解 Android相关属性的介绍:android:exported = true 在Activity中该属性用来标示:当前Acti ...

  2. 【参考】Android wm指令用法详解

    我就放些我自己大概率会用到的指令在这儿,详细的看原文地址. 原文地址:Android wm指令用法详解 - 走看看 adb shell SE:/ $ wm size        //查看当前分辨率 ...

  3. android layoutinflater用法,Android LayoutInflater的用法详解

    相信我们在开发过程中肯定接触过LayoutInflater,比如ListView的适配器里的getView方法里通过LayoutInflater.from(Context).inflater来加载xm ...

  4. Android中vector用法详解

    在安卓的发展历程中,由于设备碎片化的原故,谷歌在app中图标的适配上做出一步又一步的改进,大体有这么几个阶段: 首先有了drawable-(m|h|xh|xxh|xxxh)dpi 自android s ...

  5. android搜索功能xml,Android_Android ActionBar搜索功能用法详解,本文实例讲述了Android ActionBar - phpStudy...

    Android ActionBar搜索功能用法详解 本文实例讲述了Android ActionBar搜索功能用法.分享给大家供大家参考,具体如下: 使用ActionBar SearchView时的注意 ...

  6. php android 复制粘贴板,Android_Android剪贴板用法详解,本文实例详述了Android剪贴板的 - phpStudy...

    Android剪贴板用法详解 本文实例详述了Android剪贴板的用法,分享给大家供大家参考.具体方法分析如下: 这里首先需要注意的一点,就是在使用Android剪贴板的时候大家只记住一点就行了,不管 ...

  7. android butterknife 自定义view,ButterKnife用法详解.md

    # ButterKnife用法详解 ### 如何成为T型人才,垂直在一个行业中,必须要有一整套[知识体系](https://github.com/WeiSmart/Android-Advanced-C ...

  8. android tablayout 自定义,TabLayout用法详解及自定义样式

    TabLayout的默认样式: app:theme="@style/Widget.Design.TabLayout" 从系统定义的该样式继续深入: fill fixed 264dp ...

  9. Android Animation之ScaleAnimation用法详解

    ScaleAnimation用法详解 ScaleAnimation是Animation的子类,其有四个构造方法: 1.public ScaleAnimation(Context context, At ...

  10. Android多点触控详解

    本文转载自GcsSloop的 安卓自定义View进阶-多点触控详解 的文章 Android 多点触控详解,在前面的几篇文章中我们大致了解了 Android 中的事件处理流程和一些简单的处理方案,本次带 ...

最新文章

  1. Android中出现内存泄露的原因
  2. python基本数据类型之序列类型和映射类型
  3. Nginx upstream的5种权重分配方式分享
  4. 如何获取服务器上文件的hashcode,java获取文件hashcode
  5. 和你谈谈数据分析报告
  6. vegas9.0合成计时器
  7. LockSupport的源码实现原理以及应用
  8. 数据批量导入Oracle数据库
  9. 10大清宿便排毒方法及简单排毒瘦小腹运动
  10. 解决:A component required a bean of type ‘javax.jms.Queue‘ that could not be found.
  11. 一个action类中写多个方法需要继承MappingDispatchAction
  12. 项目工程自动化 - OCLint
  13. 几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm
  14. CTF常见用法小总结
  15. Echarts滚动条
  16. js双击编辑文本(单个)
  17. 安卓9.0刷linux,Android 9.0 内核编译实战(以一加6为例)
  18. cufflinks修改使用
  19. NE 和 KE 堆栈脚本解析
  20. 关于C#我今天的六个小时

热门文章

  1. 服务器发送消息给客户端,服务器如何发送消息给客户端
  2. python中梅花数_梅花易数中的“数字”
  3. Windows备份文件夹脚本.bat
  4. 锁仓怎么解_锁仓后解锁技巧
  5. 数字中国城市巡礼之杭州,让城市长出“神经系统”
  6. 信息可视化中的重要准则——以扇贝单词app中的可视化为例
  7. 【应用赏析】ArcGIS API for iOS在俄勒冈大学校园中的创新应用
  8. 生活随记 - 尝试与师傅沟通争取自己的权益
  9. window10运行不了1stopt_软件与win10不兼容怎么办?完美解决Win10与软件不兼容的问题...
  10. mysql 实现over函数_mysql 中如何实现over 方法(开窗函数)