适用Android系统:

1) Android版本>= 5.0

2) 部分ROM是不支持

 RemoteViews view=getRemoteViews(body,title, R.mipmap.ic_report_problem_red_24px, 0, date);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.L){
notification.headsUpContentView=view;
notification.vibrate= new long[]{ 100 };
notification.visibility = Notification.VISIBILITY_PUBLIC;
}
notification.contentView = view;

views : 自己赋值的RemoteViews,建议高度适用64dp,因为高度高了,有可能会出现截断(系统做处理)。

notification.visibility =  Notification.VISIBILITY_PUBLIC (在锁屏界面展示,具体赋值类型,请参考Notification)。

什么是通知(Notification)

通知是一个可以在应用程序正常的用户界面之外显示给用户的消息。
通知发出时,它首先出现在状态栏的通知区域中,用户打开通知抽屉可查看通知详情。通知区域和通知抽屉都是用户可以随时查看的系统控制区域。

作为安卓用户界面的重要组成部分,通知有自己的设计指南。在Android 5.0(API level 21)中引入的 Material Design 的变化是特别重要的,更多信息请阅读 通知设计指南

如何创建通知

随着Android系统不断升级,Notification的创建方式也随之变化,主要变化如下:

Android 3.0之前

Android 3.0 (API level 11)之前,使用new Notification()方式创建通知:

NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ResultActivity.class), 0); Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, content, contentIntent); mNotifyMgr.notify(NOTIFICATIONS_ID, notification);

Android 3.0 (API level 11)及更高版本

Android 3.0开始弃用new Notification()方式,改用Notification.Builder()来创建通知:

NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ResultActivity.class), 0); Notification notification = new Notification.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setContentIntent(contentIntent)
.build(); // getNotification() deprecated in API level 16 mNotifyMgr.notify(NOTIFICATIONS_ID, notification);

这里需要注意: “build()” 是Androdi 4.1(API level 16)加入的,用以替代”getNotification()”。API level 16开始弃用”getNotification()”

兼容Android 3.0之前的版本

为了兼容API level 11之前的版本,v4 Support Library中提供了NotificationCompat.Builder()这个替代方法。它与Notification.Builder()类似,二者没有太大区别。

NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ResultActivity.class), 0); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setContentIntent(contentIntent); mNotifyMgr.notify(NOTIFICATIONS_ID, mBuilder.build());

注:除特别说明外,本文将根据 NotificationCompat.Builder() 展开解析,Notification.Builder()类似。

通知基本用法

通知的必要属性

一个通知必须包含以下三项属性:

  • 小图标,对应 setSmallIcon()
  • 通知标题,对应 setContentTitle()
  • 详细信息,对应 setContentText()

其他属性均为可选项,更多属性方法请参考NotificationCompat.Builder

尽管其他都是可选的,但一般都会为通知添加至少一个动作(Action),这个动作可以是跳转到Activity、启动一个Service或发送一个Broadcas等。 通过以下方式为通知添加动作:

  • 使用PendingIntent
  • 通过大视图通知的 Action Button //仅支持Android 4.1 (API level 16)及更高版本,稍后会介绍

创建通知

1、实例化一个NotificationCompat.Builder对象

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!");

NotificationCompat.Builder自动设置的默认值:

  • priority: PRIORITY_DEFAULT
  • when: System.currentTimeMillis()
  • audio stream: STREAM_DEFAULT

2、定义并设置一个通知动作(Action)

Intent resultIntent = new Intent(this, ResultActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);

3、生成Notification对象

Notificatioin notification = mBuilder.build();

4、使用NotificationManager发送通知

// Sets an ID for the notification
int mNotificationId = 001; // Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); // Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, notification);

更新通知

更新通知很简单,只需再次发送相同ID的通知即可,如果之前的通知依然存在则会更新通知属性,如果之前通知不存在则重新创建。
示例代码:

NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status); int numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
mNotifyBuilder.setContentText("new content text")
.setNumber(++numMessages);
// Because the ID remains unchanged, the existing notification is updated.
mNotifyMgr.notify(notifyID, mNotifyBuilder.build());
...

取消通知

取消通知有如下4种方式:

  • 点击通知栏的清除按钮,会清除所有可清除的通知
  • 设置了 setAutoCancel() 或 FLAG_AUTO_CANCEL的通知,点击该通知时会清除它
  • 通过 NotificationManager 调用 cancel() 方法清除指定ID的通知
  • 通过 NotificationManager 调用 cancelAll() 方法清除所有该应用之前发送的通知

通知类型

大视图通知

通知有两种视图:普通视图和大视图。
普通视图:

大视图:

默认情况下为普通视图,可通过NotificationCompat.Builder.setStyle()设置大视图。

注: 大视图(Big Views)由Android 4.1(API level 16)开始引入,且仅支持Android 4.1及更高版本。

构建大视图通知

以上图为例:
1、构建Action Button的PendingIntent

Intent dismissIntent = new Intent(this, PingService.class);
dismissIntent.setAction(CommonConstants.ACTION_DISMISS);
PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0); Intent snoozeIntent = new Intent(this, PingService.class);
snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE);
PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);

2、构建NotificatonCompat.Builder对象

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.notification))
.setContentText(getString(R.string.ping))
.setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
// 该方法在Android 4.1之前会被忽略
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
//添加Action Button
.addAction (R.drawable.ic_stat_dismiss,
getString(R.string.dismiss), piDismiss)
.addAction (R.drawable.ic_stat_snooze,
getString(R.string.snooze), piSnooze);

3、其他步骤与普通视图相同

进度条通知

  • 明确进度的进度条
    使用setProgress(max, progress, false)来更新进度。
    max: 最大进度值
    progress: 当前进度
    false: 是否是不明确的进度条

    模拟下载过程,示例如下:

        int id = 1;
    ...
    mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mBuilder = new NotificationCompat.Builder(this);
    mBuilder.setContentTitle("Picture Download")
    .setContentText("Download in progress")
    .setSmallIcon(R.drawable.ic_notification); // Start a lengthy operation in a background thread
    new Thread(
    new Runnable() {
    @Override
    public void run() {
    int incr;
    for (incr = 0; incr <= 100; incr+=5) {
    mBuilder.setProgress(100, incr, false);
    mNotifyManager.notify(id, mBuilder.build());
    try {
    // Sleep for 5 seconds
    Thread.sleep(5*1000);
    } catch (InterruptedException e) {
    Log.d(TAG, "sleep failure");
    }
    }
    mBuilder.setContentText("Download complete")//下载完成
    .setProgress(0,0,false); //移除进度条
    mNotifyManager.notify(id, mBuilder.build());
    }
    }
    ).start();


    上图,分别为下载过程中进度条通知 和 下载完成移除进度条后的通知。

  • 不确定进度的进度条
    使用setProgress(0, 0, true)来表示进度不明确的进度条

    mBuilder.setProgress(0, 0, true); mNotifyManager.notify(id, mBuilder.build());

浮动通知(Heads-up Notifications)

Android 5.0(API level 21)开始,当屏幕未上锁且亮屏时,通知可以以小窗口形式显示。用户可以在不离开当前应用前提下操作该通知。
如图:

NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setFullScreenIntent(pendingIntent, false);

以下两种情况会显示浮动通知:

  • setFullScreenIntent(),如上述示例。
  • 通知拥有高优先级且使用了铃声和振动

锁屏通知

Android 5.0(API level 21)开始,通知可以显示在锁屏上。用户可以通过设置选择是否允许敏感的通知内容显示在安全的锁屏上。
你的应用可以通过setVisibility()控制通知的显示等级:

  • VISIBILITY_PRIVATE : 显示基本信息,如通知的图标,但隐藏通知的全部内容
  • VISIBILITY_PUBLIC : 显示通知的全部内容
  • VISIBILITY_SECRET : 不显示任何内容,包括图标

自定义通知

Android系统允许使用RemoteViews来自定义通知。
自定义普通视图通知高度限制为64dp,大视图通知高度限制为256dp。同时,建议自定义通知尽量简单,以提高兼容性。

自定义通知需要做如下操作:
1、创建自定义通知布局
2、使用RemoteViews定义通知组件,如图标、文字等
3、调用setContent()将RemoteViews对象绑定到NotificationCompat.Builder
4、同正常发送通知流程

注意: 避免为通知设置背景,因为兼容性原因,有些文字可能看不清。

定义通知文本样式

通知的背景颜色在不同的设备和版本中有所不同,Android2.3开始,系统定义了一套标准通知文本样式,建议自定义通知使用标准样式,这样有助于通知文本可见。
通知文本样式:

Android 5.0之前可用:
android:style/TextAppearance.StatusBar.EventContent.Title // 通知标题样式
android:style/TextAppearance.StatusBar.EventContent // 通知内容样式 Android 5.0及更高版本:
android:style/TextAppearance.Material.Notification.Title // 通知标题样式
android:style/TextAppearance.Material.Notification // 通知内容样式

更多通知的标准样式和布局,可参考源码frameworks/base/core/res/res/layout路径下的通知模版如:

Android 5.0之前:
notification_template_base.xml
notification_template_big_base.xml
notification_template_big_picture.xml
notification_template_big_text.xml Android 5.0 及更高版本:
notification_template_material_base.xml
notification_template_material_big_base.xml
notification_template_material_big_picture.xml
notification_template_part_chronometer.xml
notification_template_progressbar.xml 等等。

保留Activity返回栈

常规Activity

默认情况下,从通知启动一个Activity,按返回键会回到主屏幕。但某些时候有按返回键仍然留在当前应用的需求,这就要用到TaskStackBuilder了。

1、在manifest中定义Activity的关系

Android 4.0.3 及更早版本
<activity
android:name=".ResultActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>
</activity>


Android 4.1 及更高版本
<activity
android:name=".ResultActivity"
android:parentActivityName=".MainActivity">
</activity>

2、创建返回栈PendingIntent

Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// 添加返回栈
stackBuilder.addParentStack(ResultActivity.class);
// 添加Intent到栈顶
stackBuilder.addNextIntent(resultIntent);
// 创建包含返回栈的pendingIntent
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
上述操作后,从通知启动ResultActivity,按返回键会回到MainActivity,而不是主屏幕。

特殊Activity

默认情况下,从通知启动的Activity会在近期任务列表里出现。如果不需要在近期任务里显示,则需要做以下操作:

1、在manifest中定义Activity

<activity
android:name=".ResultActivity"
android:launchMode="singleTask"
android:taskAffinity=""
android:excludeFromRecents="true">
</activity>

2、构建PendingIntent

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
Intent notifyIntent = new Intent(this, ResultActivity.class); // Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent notifyPendingIntent =
PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); builder.setContentIntent(notifyPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

上述操作后,从通知启动ResultActivity,此Activity不会出现在近期任务列表中。

通知常见属性和常量

通知的提醒方式

1、声音提醒

  • 默认声音
    notification.defaults |= Notification.DEFAULT_SOUND;

  • 自定义声音
    notification.sound = Uri.parse(“file:///sdcard0/notification.ogg”);

2、震动提醒

  • 默认振动
    notification.defaults |= Notification.DEFAULT_VIBRATE;

  • 自定义振动
    long[] vibrate = {100, 200, 300, 400}; //震动效果
    // 表示在100、200、300、400这些时间点交替启动和关闭震动 notification.vibrate = vibrate;

3、闪烁提醒

  • 默认闪烁
    notification.defaults |= Notification.DEFAULT_LIGHTS;

  • 自定义闪烁
    notification.ledARGB = 0xff00ff00; // LED灯的颜色,绿灯
    notification.ledOnMS = 300; // LED灯显示的毫秒数,300毫秒
    notification.ledOffMS = 1000; // LED灯关闭的毫秒数,1000毫秒
    notification.flags |= Notification.FLAG_SHOW_LIGHTS; // 必须加上这个标志

常见的Flags

  • FLAG_AUTO_CANCEL
    当通知被用户点击之后会自动被清除(cancel)

  • FLAG_INSISTENT
    在用户响应之前会一直重复提醒音

  • FLAG_ONGOING_EVENT
    表示正在运行的事件

  • FLAG_NO_CLEAR
    通知栏点击“清除”按钮时,该通知将不会被清除

  • FLAG_FOREGROUND_SERVICE
    表示当前服务是前台服务

更多Notification属性详见Notification

Android 5.0以上heads up通知的更多相关文章

  1. 在 Xamarin.Android 中使用 Notification.Builder 构建通知

    0 背景 在 Android 4.0 以后,系统支持一种更先进的 Notification.Builder 类来发送通知.但 Xamarin 文档含糊其辞,多方搜索无果,遂决定自己摸索. 之前的代码: ...

  2. Android 8.0+ 通知不显示的适配

    最近在 写项目的时候  发现 通知并不会显示的问题,查看资料发现 从Android 8.0开始通知必须加上ChannelId Android O 引入了 通知渠道(Notification Chann ...

  3. 对Android 8.0以上版本通知点击无效的一次分析

    版权声明:本文为xing_star原创文章,转载请注明出处! 本文同步自http://javaexception.com/archives/178 对Android 8.0以上版本通知点击无效的一次分 ...

  4. Android 7.0 Nougat牛轧糖 发布啦

    Android 7.0 Nougat牛轧糖 发布啦 Android 7.0 Nougat 牛轧糖于本月发布了. 从官方blog里可以了解到这个版本的新特性. Android 7.0 从2016年8月正 ...

  5. Android 6.0 - 动态权限管理的解决方案

    Android 6.0版本(Api 23)推出了很多新的特性, 大幅提升了用户体验, 同时也为程序员带来新的负担. 动态权限管理就是这样, 一方面让用户更加容易的控制自己的隐私, 一方面需要重新适配应 ...

  6. 有史来最大改变 Android 5.0十大新特性

    有史来最大改变 Android 5.0十大新特性 2014.10.16 14:51:31 来源:腾讯数码作者:腾讯数码 ( 0 条评论 )   距离Android系统上一次重大更新不到一年的时间,谷歌 ...

  7. 【译】Android 6.0 Changes (机翻加轻微人工校对)

    Android 6.0 Changes In this document Runtime Permissions Doze and App Standby Apache HTTP Client Rem ...

  8. 谈谈Android 6.0运行时权限理解

    前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...

  9. Android 6.0 新功能及主要 API 变更

    运行时权限 这个版本中引入了新的权限模型,现在用户可以在运行时直接管理应用程序的权限.这个模型基于用户对权限控制的更多可见性,同时为应用程序的开发者提供更流畅的应用安装和自动升级.用户可以为已安装的每 ...

随机推荐

  1. 10.model/view实例(1)

    1.如图显示一个2x3的表格: 思考: 1.QTableView显示这个表 2.QAbstractTableModel作为模型类. 3.文档中找到subclass的描述 When subclassin ...

  2. 数据结构 merge_link合并链表

    问题描述 本题任务是维护一条非递减的链表,初始长度为 0,记这条链表为主链表.对主链表做 N 次操作,操作分两种:1 k a1 a2 … ak,表示一条长度为 k 且非递减的链表,需要将这条链表合并到 ...

  3. java全栈day05--ArrayList的基本功能

    在前面我们学习了数组,数组可以保存多个元素,但在某些情况下无法确定到底要保存多少个元素,此时数组将不再适用,因为数组的长度不可变.例如,要保存一个学校的学生,由于不停有新生来报道,同时也有学生毕业离开 ...

  4. 微信创建带参数二维码,并加上logo

    现在需要创建一个场景二维码,除了基础的微信接口创建外,需要加上小logo,思路如下: 1. 首先根据微信的开发文档创建二维码,获取二维码的url,没啥可说的,按照文档来就好了 获取到的二维码就是这么素 ...

  5. Unity自带IAP插件使用(googleplay)

    https://blog.csdn.net/ar__ha/article/details/64439872 Unity Services里的Unity IAP对于IOS和GooglePlay的支付用这 ...

  6. 【Linux】-Ubuntu下配置JDK1.8

    前言 这次实在是不想写前言了,好吧,那咱就不写了. 内容 怀着复杂的心情来整理这个小小的操作,其实我的内心是拒绝的,因为太简单了,但是我却花费了很长的时间,有效时间花费了将近两个小时去整理这个小玩意儿 ...

  7. hdu4651(广义五边形数 & 分割函数1)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4651 题意:f(x) 为将 x 分成其他数和的形式的方案数.对于 t 组输入,输出 f(xi). 思路 ...

  8. SP34096 DIVCNTK - Counting Divisors (general)(Min_25筛)

    题面 洛谷 \(\sigma_0(i)\) 表示\(i\) 的约数个数 求\(S_k(n)=\sum_{i=1}^n\sigma_0(i^k)\mod 2^{64}\) 多测,\(T\le10^4,n ...

  9. ObjectARXWizards & AutoCAD .NET Wizards 下载地址

    Autodesk Developer Network ObjectARX Wizards The ObjectARX Wizards for AutoCAD 2016 for  Visual Stud ...

  10. Linux下的hosts文件和network文件区别

    Linux下的hosts文件和network文件区别   Linux下有两种与计算机名相关的配置文件     1.hosts文件,路径:/etc/hosts,此文间是在网络上使用的, 用于解析计算机名 ...