一、通知(Notification)

通知是可以在应用常规UI外部向用户显示的消息。通常使用NotificationCompat.Builder对象构建UI信息和操作,NotificationCompat.Builder.build()返回具体的Notification对象,最后通过调用NotificationManager.notify()将Notification对象传递给系统。

Notification必须包含以下内容:小图标(smallIcon),标题(ContentTitle),详细文本(ContentText)。

通知操作:当用户点击时触发的操作。一般会在应用打开Activity。在Notification内部,操作由PendingIntent定义,后者包含在应用中启动activity的Intent,通过setContentIntent()来添加PendingIntent。

通知优先级:优先级用于提醒设备UI如何显示通知。通过NotificationCompat.Builder,setPriority()并传入一个NotificationCompat优先级常量。共五个,从PRIORITY_MIN(-2)到PRIORITY_MAX(2);默认为PRIORITY_DEFAULT(0);

创建简单通知:

NotificationCompat.Builder mBuilder =        new NotificationCompat.Builder(this)        .setSmallIcon(R.drawable.notification_icon)        .setContentTitle("My notification")        .setContentText("Hello World!");...NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// mId用于之后更新notificationmNotificationManager.notify(mId, mBuilder.build());
扩展布局:在4.1之前不可用。

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)    .setSmallIcon(R.drawable.notification_icon)    .setContentTitle("多文本可扩展标题")    .setContentText("多文本可扩展内容")    // 多文本,可扩展    .setStyle(new NotificationCompat.BigTextStyle()            .bigText(msg))    .addAction (R.drawable.ic_stat_dismiss,            getString(R.string.dismiss), piDismiss)    .addAction (R.drawable.ic_stat_snooze,            getString(R.string.snooze), piSnooze);...
兼容性处理:如,扩展通知仅在Android4.1及更高版本可用等。

为了确保兼容性,需要使用NorificationCompat及其子类创建通知。此外请遵循以下流程:

1.为用户提供通知的全部功能,无论何种版本的Android系统。因此要验证是否可以从应用的Activity中获得所有功能。要实现这个要求,可能要添加新的Activity;例如,若要使用addAction()提供停止和启动媒体播放的控件,应先在Activity中实现此控件。

2.确保用户均可通过点击通知启动Activity来获得该Activity中的功能。为此,要创建PendingIntent。调用setContentIntent()以将PendingIntent添加到通知。

3.将要使用的扩展通知功能添加到通知。添加的任何功能必须在用户点击通知时启动的activity中可用。

二、通知管理

1.更新通知

同一类型的事件多次发生时,要避免重新发送多次的通知。使用notify()所用的通知ID来更新或创建通知。

mNotificationManager =        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// 设置通知id,以便更新int notifyID = 1;mNotifyBuilder = new NotificationCompat.Builder(this)    .setContentTitle("New Message")    .setContentText("You've received new messages.")    .setSmallIcon(R.drawable.ic_notify_status)numMessages = 0;// 启动轮询处理数据,并通知用户...    mNotifyBuilder.setContentText(currentText)        .setNumber(++numMessages);    // 设置该类型通知有多少个    // 只要id一致,则通知就会更新而不是新建    mNotificationManager.notify(            notifyID,            mNotifyBuilder.build());...

2.删除通知

用户单独或通过使用“全部清除”清除了该通知(如果通知可以清除);

用户点击通知,并且创建通知时调用了setAutoCancel();

针对特定的通知ID调用了cancel()。此方法还会删除当前通知;

调用了cancelAll()方法,该方法删除之前所发出的所有通知。

三、启动Activity时保留导航

从通知启动Activity时,必须保留用户的预期导航体验。点击“返回”应使用户将应用的正常工作流返回到主屏幕,点击“最新动态”则应将Activity显示为单独的任务。要保留导航体验,应该在全新任务中启动Activity。如何设置PendingIntent以获得全新任务取决于启动的Activity的性质。一般有两种情况:

1.常规Activity

要启动的Activity是应用的正常工作流的一部分。这种情况下,设置PendingIntent以启动全新任务并为PendingIntent提供返回栈,这将重现应用的正常“返回”行为。例如正在别的应用时,点击了邮件的通知,点击返回,则会依次转到收件箱和主屏幕,而不是之前的那个应用。

1)在清单文件中定义应用的Activity层次结构;

a.添加对Android4.0.3及更低版本的支持。通过添加元素作为的子项来指定正在启动的Activity的父项(父Activity)。

b.添加对Android4.1及更高版本的支持,将android:parentActivityName属性添加到正在启动的Activity的元素中。

示例如下:

                            
2)根据可启动Activity的Intent创建返回栈:

a.创建Intent以启动Activity;

b.通过TaskStackBuilder.create()创建堆栈生成器;

c.通过调用addParentStack()将返回栈添加到堆栈生成器。对于在清单文件中所定义层次结构内的每个Activity,返回栈均可包含可启动Activity的Intent对象。此方法还会添加一些可在全新任务中启动堆栈的标志。(注:尽管addParentStack()的参数是对已启动Activity的引用,但是方法调用不会添加可启动Activity的Intent,而是留待下一步进行处理)

d.如果调用addNextIntent(),添加可从通知中启动Activity的Intent。将在第一步中创建的Intent作为addNextIntent的参数传递。

e.如需,通过调用TaskStackBuilder.editIntentAt()向堆栈中的Intent对象添加参数。有时,需要确保目标Activity在用户使用“返回”导航回它时会显示有意义的数据。

f.调用getPendingIntent()获得此返回栈的PendingIntent。使用此PendingItent作为setContentIntent()的参数。

...Intent resultIntent = new Intent(this, ResultActivity.class);TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);// 添加返回栈stackBuilder.addParentStack(ResultActivity.class);// 将intent添加到栈顶stackBuilder.addNextIntent(resultIntent);// 获取包含全部返回栈的PendingIntentPendingIntent 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());

注意:此处的示例在模拟器上可能展现不出效果。

2.特殊Activity

仅当从通知启动时,用户才会看到此Activity。可以视Activity为通知的扩展。这种情况将PendingIntent设置为在全新的任务中启动。但由于启动的Activity不是应用Activity流程的一部分,因此无需创建返回栈。点击返回会将用户带到主屏幕。

不必在清单文件中定义Activity层次结构,也不必调用addParentStack()来构建返回栈。可以使用清单文件设置Activity任务选项,并通过调用getActivity()创建PendingIntent:

1)在清单中添加以下属性:

android:name="activityclass",全限定类名;

android:taskAffinity="",与在代码中设置的FLAG_ACTIVITY_NEW_TASK标志相结合,确保Activity不会进入应用的默认任务。任何具有应用默认关联的现有任务均不受影响。

android:excludeFromRecents="true",将新任务从“最新动态”中排除,这样用户就不会再无意中导航回它。

示例:

2)构建并发出通知

a.创建可启动Activity的Intent;

b.通过使用FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK标志调用setFlags(),将Activity设置为在新的空任务中启动;

c.为Intent设置所需的任何其他选项;

d.调用getActivity()从Intent中创建PendingIntent。使用该PendingIntent作为setContentIntent的参数。
示例:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);// 为activity创建intentIntent notifyIntent = new Intent(this, ResultActivity.class);// 设置activity启动一个新的空栈notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);// 创建PendingIntentPendingIntent notifyPendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);// 把PendingIntent放到builder中builder.setContentIntent(notifyPendingIntent);// Notifications 发送给 NotificationManagerNotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// 通过builder构建一个匿名Notification对象并传递给NotificationManagermNotificationManager.notify(id, builder.build());

四、在通知中显示进度

通知中可以显示进度条。如果可以估计操作时间以及完成进度,使用可指定进度的进度条。否则,使用无限循环进度条。

要在Android4.0及更高版本的平台上使用进度条,要调用setProgress()。早期版本,需要创建包含ProgressBar视图的自定义通知布局。

1.显示持续时间固定的进度指示器

通过setProgress(max, progress, false)将进度栏添加到通知,然后发出通知。操作结束,progress等于max。常见方式是,max为100,progress作为百分比值递增。

操作完成后可以保留进度栏,也可删除。但是都要更新通知文本以显示操作已完成。要删除进度栏,调用setProgress(0, 0, false)。

...mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);mBuilder = new NotificationCompat.Builder(this);mBuilder.setContentTitle("Picture Download")    .setContentText("Download in progress")    .setSmallIcon(R.drawable.ic_notification);// 在后台线程进行冗长操作new Thread(    new Runnable() {        @Override        public void run() {            int incr;            // 20次冗长操作            for (incr = 0; incr <= 100; incr+=5) {                    // 设置进度指示器最大值,完成值,确定状态                    mBuilder.setProgress(100, incr, false);                    // 第一次时,显示进度栏                    mNotifyManager.notify(0, mBuilder.build());                        try {                            Thread.sleep(5*1000);                        } catch (InterruptedException e) {                            Log.d(TAG, "sleep failure");                        }            }            // 当循环完成,更新notification            mBuilder.setContentText("Download complete")            // 移除进度栏                    .setProgress(0,0,false);            mNotifyManager.notify(ID, mBuilder.build());        }    }// 启动线程).start();

2.显示持续Activity指示器

使用setProgress(0, 0, true)添加到通知(忽略前两个参数),然后发出通知。setProgress(0, 0, false)可以删除指示器,不删除的话会一直显示。

五、自定义通知布局

使用RemoteViews对象自定义通知布局。自定义布局的可用高度取决于通知视图。普通视图布局限制为64dp,扩展视图布局限制为256dp。

首先实例化RemoteViews来扩充XML布局文件,调用setContent()方法设置详细内容,注意要使用RemoteViews中的方法设置视图子项的值:

1.在单独文件中为通知创建XML布局。

2.避免为RemoteViews设置背景Drawable,背景色可能使文本难以阅读。

这里按照文档描述的很简洁,以后出一个RemoteViews的详细版本。

六、其他功能

1.通知元数据(NotificationCompat.Builder)

1)当设备处于“优先”模式时,setCategory()会告知系统如何处理应用通知(如,通知代表电话呼入、消息、闹铃);

2)如果优先级设为PRIORITY_MAX或PRIORITY_HIGH,通知会有声音或振动,则setPriority()会将其显示在小型浮动窗口中;

3)addPerson()允许向通知添加人员名单。

2.浮动通知

5.0之后,设备处于活动状态时,即屏幕已打开,可以显示为浮动通知(在屏幕顶部出现notification,不需要拉开就能看见)。也可以提供一些操作按钮。

触发条件包括:用户的Activity处于全屏模式中(应使用fullScreenIntent),或者通知具有较高的优先级并使用铃声或振动。

fullScreenIntent要使用bulder.setFullScreenIntent(pendingIntent, true);// 官网上说有些系统会选择直接启动该Activity,有些则会显示为浮动通知。测三个真机都直接启动。

3.锁定屏幕通知

5.0之后,通知可以显示在锁定屏幕上。可以用此功能提示媒体播放控件。用户在“设置”中可选择通知是否显示在锁定屏幕上。

1)调用setVisibility()指定是否可见:

a.VISIBILITY_PUBLIC:显示通知的完整内容;

b.VISIBILITY_SECRET:不在锁定屏幕上显示;

c.VISIBILITY_PRIVATE:显示通知图标和内容等基本信息,隐藏内容。

这里是指在锁屏状态可以看见通知,但是不好说,国内定制机太多,像华为荣耀就不显示,魅族会显示,但是上面几个可见性不起作用,魅族全部显示。

2)锁屏状态控制媒体播放

Android5.0(API21),锁屏不再基于RemoteControlClient显示媒体控件。而是用Notification.MediaStyle与addAction()方法结合。后者将操作转换为可点击的图标。

注意:该模板和addAction()方法未包含在支持库中,因此只有5.0及以上版本才能支持。且要将可见性设置为VISIBILITY_PUBLIC。

下面给出代码,测试的时候魅族可以显示,华为荣耀7可以在下拉的通知栏里显示,但是不显示在锁屏屏幕上。

Notification notification = new Notification.Builder(context)    // 设置可见性    .setVisibility(Notification.VISIBILITY_PUBLIC)    .setSmallIcon(R.drawable.ic_stat_player)    // 添加媒体控制按钮调用媒体service中的intent。    .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0    .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)  // #1    .addAction(R.drawable.ic_next, "Next", nextPendingIntent)     // #2    // 应用媒体style模板    .setStyle(new Notification.MediaStyle()    .setShowActionsInCompactView(1 /* #1: pause button */)    .setMediaSession(mMediaSession.getSessionToken())    .setContentTitle("Wonderful music")    .setContentText("My Awesome Band")    .setLargeIcon(albumArtBitmap)    .build();


更多相关文章

  1. android启动之SystemServer启动
  2. Android(安卓)Toast用法
  3. Android启动过程 && Activity的生命周期 && Activity的开机自启
  4. 【Android学习笔记1】Android(安卓)Studio 开发环境安装笔记(wind
  5. Android(安卓)Notification 兼容3.0到8.0
  6. android中,显示圆形图片
  7. Android中用ListView显示网络下载的Bitmap
  8. 推荐4款开源的Android引导页控件
  9. Android(安卓)4.4.2 禁用通知栏下拉

随机推荐

  1. android点击EditText外区域收起键盘
  2. Error:more than one library with packa
  3. Android——SeekBar(进度、音量大小的控件
  4. Android中保存图片到本地并更新到相册及
  5. Android(安卓)SystemUI 闪烁
  6. Android中应用的快捷方式的创建
  7. android使用HttpURLConnection上传文件同
  8. Android中四大组件概述以及各自作用
  9. android之ScrollView里嵌套ListView
  10. Android(安卓)Things正式版发布啦