其他分享
首页 > 其他分享> > Notification

Notification

作者:互联网

最近时不时地有人问我这样或那样的通知如何实现,所以本文将根据个人经验对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()

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()类似。

通知基本用法

通知的必要属性

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

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

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

创建通知

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

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

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

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;
...
    mNotifyBuilder.setContentText("new content text")
            .setNumber(++numMessages);
    mNotifyMgr.notify(notifyID, mNotifyBuilder.build());
...

取消通知

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

通知类型

大视图通知

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


大视图:

默认情况下为普通视图,可通过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)
        // 该方法在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、其他步骤与普通视图相同

进度条通知

浮动通知(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);

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

锁屏通知

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

自定义通知

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、声音提醒

2、震动提醒

3、闪烁提醒

常见的Flags


8.0的适配变动,可以参考:Android O(8.0) Notification解决方案 - 简书
转自:https://www.jianshu.com/p/22e27a639787

 

标签:Notification,Builder,NotificationCompat,通知,notification,new
来源: https://blog.csdn.net/wangsen927/article/details/120843195