转载自 http://www.cnblogs.com/travellife/css
html
Notification,是一种具备全局效果的通知,能够在系统的通知栏中显示。当 APP 向系统发出通知时,它将先以图标的形式显示在通知栏中。用户能够下拉通知栏查看通知的详细信息。通知栏和抽屉式通知栏均是由系统控制,用户能够随时查看。下面两张图均是来自 Google 官方文档。java

图 1 .通知栏中的通知android

图 2 .抽屉式通知栏中的通知git
通知的目的是告知用户 App 事件。在平时的使用中,通知主要有如下几个做用:github
其中,前两点能够归结为与用户交互,第三点是实时的任务提醒,但不能否认的是,第三点也会与用户交互。微信
Notification 做为 Android 重要的用户界面组成部分,它有本身的设计指南。在 Android 5.0(Api level 21) 中引入的 Material Design 尤其重要。关于 Notification 的设计指南请参考 Notification Pattern并发
Notification 的概述就这么多,接下去就开始讲 Notification 的基本使用,中间会穿插 Notification 的基本 UI 、各个版本的区别、常见的通知效果以及本身在学习过程当中踩到的坑。less
Notification 的基本操做主要有建立、更新、取消这三种。一个 Notification 的必要属性有三项,若是不设置则在运行时会抛出异常:ide
除了以上三项,其它均为可选项。虽然如此,但仍是应该给 Notification 设置一个 Action ,这样就能够直接跳转到 App 的某个 Activity 、启动一个 Service 或者发送一个 Broadcast。不然,Notification 仅仅只能起到通知的效果,而不能与用户交互。
当系统接收到通知时,能够经过震动、响铃、呼吸灯等多种方式进行提醒。
Notification 的建立主要涉及到 Notification.Builder 、 Notification 、 NotificationManager 。
获取 NotificationManager 对象:
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
前面讲到,Notification 有三个必要属性。下面,咱们就来建立一个简单的 Notification 。主要有如下三步:
private void sendNotification() { //获取NotificationManager实例 NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); //实例化NotificationCompat.Builde并设置相关属性 NotificationCompat.Builder builder = new NotificationCompat.Builder(this) //设置小图标 .setSmallIcon(R.mipmap.icon_fab_repair) //设置通知标题 .setContentTitle("最简单的Notification") //设置通知内容 .setContentText("只有小图标、标题、内容") //设置通知时间,默认为系统发出通知的时间,一般不用设置 //.setWhen(System.currentTimeMillis()); //经过builder.build()方法生成Notification对象,并发送通知,id=1 notifyManager.notify(1, builder.build()); }
以上代码是对 Android 3.0 及以后的版本而言(包括使用 Support Library),对于 Android 3.0 以前的版本,主要使用 new Notification() 方法来建立 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 Support v4:这个包是为了照顾1.6及更高版本而设计的,这个包是使用最普遍的。 Android Support v7:这个包是为了考虑照顾2.1及以上版本而设计的,但不包含更低,故若是不考虑1.6,咱们能够采用再加上这个包,另外注意,v7是要依赖v4这个包的,即,两个得同时被包含。 Android Support v13:这个包的设计是为了android 3.2及更高版本的,通常咱们都不经常使用,平板开发中能用到。
Google 官方是这么解释 setSmallIcon()
这个方法的:
Set the small icon resource, which will be used to represent the notification in the status bar. The platform template for the expanded view will draw this icon in the left, unless a large icon has also been specified, in which case the small icon will be moved to the right-hand side.
在前一章节 建立 Notification 中发送的通知并不具有与用户交互的能力,这是由于咱们并无给 Notification 设置 Action 。在这一节,咱们就来说讲如何给 Notification 设置 Action 。这里,咱们来实现一个点击 Notification 跳转到 MainActivity 的效果。代码以下:
/** * 发送一个点击跳转到MainActivity的消息 */ private void sendSimplestNotificationWithAction() { //获取PendingIntent Intent mainIntent = new Intent(this, MainActivity.class); PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT); //建立 Notification.Builder 对象 NotificationCompat.Builder builder = new NotificationCompat.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) //点击通知后自动清除 .setAutoCancel(true) .setContentTitle("我是带Action的Notification") .setContentText("点我会打开MainActivity") .setContentIntent(mainPendingIntent); //发送通知 mNotifyManager.notify(3, builder.build()); }
相比发送最简单的通知,发送具备 Action 的通知多了建立 Intent 、 PendingIntent 和 setContentIntent() 这几步。
不难看出, PendingIntent 才是重点,那么, PendingIntent 是什么呢?
若是您了解 PendingIntent ,请直接跳过本节。
PendingIntent 是一种特殊的 Intent ,字面意思能够解释为延迟的 Intent ,用于在某个事件结束后执行特定的 Action 。从上面带 Action 的通知也能验证这一点,当用户点击通知时,才会执行。
PendingIntent 是 Android 系统管理并持有的用于描述和获取原始数据的对象的标志(引用)。也就是说,即使建立该PendingIntent对象的进程被杀死了,这个PendingItent对象在其余进程中仍是可用的。
平常使用中的短信、闹钟等都用到了 PendingIntent。
PendingIntent 主要能够经过如下三种方式获取:
//获取一个用于启动 Activity 的 PendingIntent 对象 public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags); //获取一个用于启动 Service 的 PendingIntent 对象 public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags); //获取一个用于向 BroadcastReceiver 广播的 PendingIntent 对象 public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
PendingIntent 具备如下几种 flag:
FLAG_CANCEL_CURRENT:若是当前系统中已经存在一个相同的 PendingIntent 对象,那么就将先将已有的 PendingIntent 取消,而后从新生成一个 PendingIntent 对象。 FLAG_NO_CREATE:若是当前系统中不存在相同的 PendingIntent 对象,系统将不会建立该 PendingIntent 对象而是直接返回 null 。 FLAG_ONE_SHOT:该 PendingIntent 只做用一次。 FLAG_UPDATE_CURRENT:若是系统中已存在该 PendingIntent 对象,那么系统将保留该 PendingIntent 对象,可是会使用新的 Intent 来更新以前 PendingIntent 中的 Intent 对象数据,例如更新 Intent 中的 Extras 。
更新通知很简单,只须要再次发送相同 ID 的通知便可,若是以前的通知还未被取消,则会直接更新该通知相关的属性;若是以前的通知已经被取消,则会从新建立一个新通知。
更新通知跟发送通知使用相同的方式。详见上节:建立 Notification
取消通知有以下 5 种方式:
若是你是经过 NotificationManager.notify(String tag, int id, Notification notify) 方法建立的通知,那么只能经过 NotificationManager.cancel(String tag, int id) 方法才能清除对应的通知,调用NotificationManager.cancel(int id) 无效。
关于 Notification 的基本操做代码以下,布局文件代码这就不贴了。我是 Demo 传送门:
/** * 为了方便,大部分通知都没设置对应的Action,即PendingIntent * 除了sendFlagAutoCancelNotification()方法 */ public class SimpleNotificationActivity extends Activity implements View.OnClickListener { //Notification.FLAG_FOREGROUND_SERVICE //表示正在运行的服务 public static final String NOTIFICATION_TAG = "littlejie"; public static final int DEFAULT_NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_simple_notification); findViewById(R.id.btn_remove_all_notification).setOnClickListener(this); findViewById(R.id.btn_send_notification).setOnClickListener(this); findViewById(R.id.btn_remove_notification).setOnClickListener(this); findViewById(R.id.btn_send_notification_with_tag).setOnClickListener(this); findViewById(R.id.btn_remove_notification_with_tag).setOnClickListener(this); findViewById(R.id.btn_send_ten_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_no_clear_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_ongoing_event_notification).setOnClickListener(this); findViewById(R.id.btn_send_flag_auto_cancecl_notification).setOnClickListener(this); mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_remove_all_notification: //移除当前 Context 下全部 Notification,包括 FLAG_NO_CLEAR 和 FLAG_ONGOING_EVENT mNotificationManager.cancelAll(); break; case R.id.btn_send_notification: //发送一个 Notification,此处 ID = 1 sendNotification(); break; case R.id.btn_remove_notification: //移除 ID = 1 的 Notification,注意:该方法只针对当前 Context。 mNotificationManager.cancel(DEFAULT_NOTIFICATION_ID); break; case R.id.btn_send_notification_with_tag: //发送一个 ID = 1 而且 TAG = littlejie 的 Notification //注意:此处发送的通知与 sendNotification() 发送的通知并不冲突 //由于此处的 Notification 带有 TAG sendNotificationWithTag(); break; case R.id.btn_remove_notification_with_tag: //移除一个 ID = 1 而且 TAG = littlejie 的 Notification //注意:此处移除的通知与 NotificationManager.cancel(int id) 移除通知并不冲突 //由于此处的 Notification 带有 TAG mNotificationManager.cancel(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID); break; case R.id.btn_send_ten_notification: //连续发十条 Notification sendTenNotifications(); break; case R.id.btn_send_flag_no_clear_notification: //发送 ID = 1, flag = FLAG_NO_CLEAR 的 Notification //下面两个 Notification 的 ID 都为 1,会发现 ID 相等的 Notification 会被最新的替换掉 sendFlagNoClearNotification(); break; case R.id.btn_send_flag_auto_cancecl_notification: sendFlagOngoingEventNotification(); break; case R.id.btn_send_flag_ongoing_event_notification: sendFlagAutoCancelNotification(); break; } } /** * 发送最简单的通知,该通知的ID = 1 */ private