Android Notifications通知应用详解

来源:互联网 发布:刀路模拟软件 编辑:程序博客网 时间:2024/05/21 16:02

http://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationUI

Android通知共提供了三种通知的方式:Toast Notifications、Status Bar Notification、Dialog Notification。

现在我们分别来看看他们使适用的场景和使用方法及相关案例。


(1)Toast Notifications

以背景改变方式,提示一些简短的消息,消息窗口自动淡入淡出,不接受相关的交互事件。

例如:当下载某个文件时,下载完成后,可以提示简短的信息==“保存成功”;等等


创建弹出提示方法:

1.创建Toast对象,可以通过Toast提供的静态方法makeText(Context context,String message,int duration)

context:应用上下文对象,这里可以传递getApplicationContext()

message:提示文本

duration:显示时长,可以使用Toast.LENGTH_SHORT、Toast.LENGTH_LONG

Context context=getApplicationContext();

Toast toast=Toast.mekeText(context,"保存成功",Toast.LENGTH_LONG);


2.显示提示信息,调用show()方法

toast.show();

上述两步也可简写为

Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_LONG).show(); 


3自定义外观Toast通知

3.1、定义XML资源视图作为提示的外观

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.               android:id="@+id/toast_layout_root" 
  4.               android:orientation="horizontal" 
  5.               android:layout_width="fill_parent" 
  6.               android:layout_height="fill_parent" 
  7.               android:padding="10dp" 
  8.               android:background="#DAAA" 
  9.               > 
  10.     <ImageView android:id="@+id/image" 
  11.                android:layout_width="wrap_content" 
  12.                android:layout_height="fill_parent" 
  13.                android:layout_marginRight="10dp" 
  14.                android:src="@drawable/icon" 
  15.                /> 
  16.     <TextView android:id="@+id/text" 
  17.               android:layout_width="wrap_content" 
  18.               android:layout_height="fill_parent" 
  19.               android:textColor="#FFF" 
  20.               /> 
  21. </LinearLayout> 
其中TextView文本组件用来显示需要提示的文本。这里默认没有设置文字。

3.2、解析上述XML资源视图,并设置提示文本

  1. LayoutInflater inflater = getLayoutInflater();//XML资源布局填充对象 
  2. View layout = inflater.inflate(R.layout.toast_layout, (ViewGroup) findViewById(R.id.toast_layout_root)); 
  3.  
  4. //修改自定义布局中TextView文本,作为提示信息 
  5. TextView textView = (TextView) layout.findViewById(R.id.text); 
  6. textView.setText("自定义界面:保存成功"); 

3.3、创建Toast对象,并设置视图、显示视图

  1. Toast toast = new Toast(getApplicationContext()); 
  2. //设置垂直居中,水平、垂直偏移值为0,表示正中间。 
  3. toast.setGravity(Gravity.CENTER_VERTICAL, 00);//设置提示框位置,三个参数分别代表:对其方式、水平偏移值、垂直偏移值。 
  4. toast.setDuration(Toast.LENGTH_LONG); 
  5. toast.setView(layout);//设置显示的视图 
  6. toast.show(); 


(2)Status Bar Notification

状态栏通知,当某个应用处于后台运行时需要提示用户某些信息时,不可能启动Activity。此时使用状态栏通知就非常适合用此种方法进行通知

状态栏(status bar)通知允许应用程序以不干扰当前activity的方式将事件通知用户。

可以给通知绑定一个意图(intent),当用户点击时系统会执行此意图。

状态栏(status bar)通知将一个图标填加到系统的状态栏中(包含一条可选的提示文本信息),并将一条展开信息添加到通知窗口中。当用户选中展开信息时,Android将执行一个此通知已定义的意图Intent(通常用于弹出一个Activity)。你还可以对通知进行配置,用设备提供的声音、振动、闪光来提醒用户。

当后台服务(Service)需要对某个事件发出提醒并且需要用户响应时,状态栏通知就能发挥作用了。后台服务从来不会启动Activity来接收用户的交互,取而代之的是应该创建一个状态栏通知,在用户点选后再由通知来启动Activity。


基础知识
  Activity或者Service都能初始化一个状态栏通知。可因为Activity只有在活动状态并获得焦点时才能执行操作,所以还是建议用Service来创建状态栏通知。这样,即使用户正在使用其他程序或者设备已经休眠时,仍然可以从后台创建通知。要创建一个通知,须用到两个类:Notification类和NotificationManager类。
  用Notification类的一个实例来定义状态栏通知的属性,比如图标、展开信息,以及播放声音等附属设置。NotificationManager是一个Android系统服务,用于管理和运行所有通知。NotificationManager不能被实例化,为了把Notification传给它,你可以用getSystemService()方法获取一个NotificationManager的引用。在需要通知用户时再调用notify()方法将Notification对象传给它。


要创建一个状态栏通知:

1. 获取NotificationManager的引用:

String ns = Context.NOTIFICATION_SERVICE; 

NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

2. 实例化Notification:

int icon = R.drawable.notification_icon; 

CharSequence tickerText = "Hello"; 

long when = System.currentTimeMillis(); 

Notification notification = new Notification(icon, tickerText, when);

3. 指定通知的展开信息和Intent:

Context context = getApplicationContext(); 

CharSequence contentTitle = "My notification"; 

CharSequence contentText = "Hello World!"; 

Intent notificationIntent = new Intent(this, MyClass.class); 

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

4. 将Notification对象传给NotificationManager:

private static final int HELLO_ID = 1;  

mNotificationManager.notify(HELLO_ID, notification);

好了,现在用户已经能看到通知了。

管理通知

系统服务NotificationManager管理着所有的通知,只能通过getSystemService()方法来获取它的引用。例如:

String ns = Context.NOTIFICATION_SERVICE; 

NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

如果想要发送状态栏通知,通过notify(int, Notification)传递Notification对象给NotificationManager即可。第一个参数是Notification 的唯一ID,第二个参数是Notification对象。ID在整个应用程序范围内唯一标识Notification。Notification需要更新;应用程序可能管理着多种不同的通知,在用户通过各自定义的Intent返回应用程序时必须能选择正确的动作执行之,因此上述参数是必需的。

要实现用户从通知窗口内点选后自动清除状态栏通知,请在Notification对象中加入“FLAG_AUTO_CANCEL”标志。也可以传入通知ID用cancel(int)手动清除,或者用cancelAll()清除所有你创建的通知。

创建通知

Notification对象定义了通知消息显示在状态栏和通知窗口上的细节内容,以及其他提醒设置(比如:声音、闪光等)。

状态栏通知必须包括以下内容:

· 状态栏图标

· 展开窗口view的标题和展开信息(除非用了自定义展开view

· PendingIntent,当通知被点选时执行

状态栏通知的可选设置包括:

· 状态栏提示信息

· 提醒声音

· 震动设置

· LED灯闪光设置

Notification的基础库(译者注:原文是starter-kit,但综合上下文并非“初学者套件”的意思,这里译为基础库)里包含了构造方法Notification(int, CharSequence, long)setLatestEventInfo(Context, CharSequence, CharSequence, PendingIntent)方法。这已经可以定义Notification的所有设置。以下代码段演示了对通知基本的设置:

int icon = R.drawable.notification_icon;        // icon from resources 

CharSequence tickerText = "Hello";              // ticker-text 

long when = System.currentTimeMillis();         // notification time 

Context context = getApplicationContext();      // application Context 

CharSequence contentTitle = "My notification";  // expanded message title 

CharSequence contentText = "Hello World!";      // expanded message text 

 

Intent notificationIntent = new Intent(this, MyClass.class); 

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

 

// the next two lines initialize the Notification, using the configurations above 

Notification notification = new Notification(icon, tickerText, when); 

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

更新通知

应用程序可以在事件正在进行时更新状态栏通知。比如,前一条短信还未读,可又来了一条新短信,短信程序为了正确显示未读短信的总数,可以更新已有的通知。此时,更新原有通知要比向NotificationManager新增一条通知更合理些,因为避免了通知窗口的显示混乱。

因为NotificationManager对每个通知都用一个整数ID进行了唯一标识,新的通知内容可以用setLatestEventInfo()方法方便地进行修改,然后再次调用notify()显示出来。

除了Context、展开信息的标题和文本外,可以利用对象的成员值修改每个属性。要修改通知的文本信息,只能对contentTitlecontentText参数赋新值并调用setLatestEventInfo()然后再调用notify()方法来更新通知。(当然,如果已经创建了自定义扩展view,那么标题和文本的修改就无效了)。

添加声音

可以用缺省提示音(由用户指定)或者程序指定声音来提醒用户。

要使用用户缺省提示音,给defaults属性添加“DEFAULT_SOUND”:

notification.defaults |= Notification.DEFAULT_SOUND;

要使用应用程序指定的声音,则传递一个Uri引用给sound属性。以下例子使用已保存在设备SD卡上的音频文件作为提示音:

notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");

在下面的例子里,音频文件从内部MediaStore类的ContentProvider中获取:

notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");

这时,已知有资源ID为6的媒体文件,并且已添加到Uri内容中。如果不知道确切的ID,则必须先用ContentResolver查询MediaStore中所有可用的资源。关于使用ContentResolver的详细信息请参阅Content Providers文档。

如果期望在用户响应通知或取消通知前,声音一直持续循环播放,可以把 “FLAG_INSISTENT” 加入flags属性中。

注意:如果defaults属性包含了“DEFAULT_SOUND”,则缺省提示音将覆盖sound 属性里指定的声音。

添加振动

可以用缺省震动模式或程序指定的振动模式来提醒用户。

要用缺省震动模式,给属性defaults 添加“DEFAULT_VIBRATE” 即可:

notification.defaults |= Notification.DEFAULT_VIBRATE;

要自定义震动模式,须给vibrate属性传递一个long 类型的数组:

long[] vibrate = {0,100,200,300}; 

notification.vibrate = vibrate;

长整型数组定义了震动开和关交替的时间(毫秒)。第一个数是开始振动前的等待时间(震动关闭),第二个数是第一次开启振动的持续时间,第三个数是下一次关闭时间,如此类推。振动模式的持续时间没有限制,但不能设置为重复振动。

注意:如果defaults 属性包含了“DEFAULT_VIBRATE”,则缺省的震动模式将会覆盖vibrate 属性里指定的模式。

添加闪光

要想用LED闪光来提醒用户,可以执行缺省闪光模式(如果可用的话),也可以自定义闪光的颜色和模式。

要使用缺省的闪光设置,给属性defaults 添加“DEFAULT_LIGHTS”即可:

notification.defaults |= Notification.DEFAULT_LIGHTS;

要自定义颜色和模式,则须指定ledARGB属性(指颜色)、ledOffMS属性(闪光关闭毫秒数)、ledOnMS属性(闪光开启毫秒数),并在“flags”属性里加入“FLAG_SHOW_LIGHTS”:

notification.ledARGB = 0xff00ff00; 

notification.ledOnMS = 300; 

notification.ledOffMS = 1000; 

notification.flags |= Notification.FLAG_SHOW_LIGHTS;

上例实现了绿色光闪烁300毫秒间歇1秒的闪光。每个设备的LED灯不可能支持所有颜色的发光,不同的设备所能支持的颜色也各不相同,因此硬件将按照最接近的颜色来发光。绿色是最常见的提醒色。

其他特性

利用Notification的属性和标志位,可以给通知添加更多的特性。

下面列出了其中一些常用的特性:

“FLAG_AUTO_CANCEL”标志

flags属性中增加此标志,则在通知窗口点选后能自动取消通知。

“FLAG_INSISTENT”标志

flags属性中增加此标志,则在用户响应前一直循环播放声音。

“FLAG_ONGOING_EVENT”标志

flags属性中增加此标志,则将通知放入通知窗口的“正在运行”(Ongoing)组中。表示应用程序正在运行——进程仍在后台运行,即使应用程序不可见(比如播放音乐或接听电话)。

“FLAG_NO_CLEAR”标志

flags属性中增加此标志,表示通知不允许被“清除通知”按钮清除。这在期望通知保持运行时特别有用。

number属性

表示通知所代表的事件数量。此数字显示在状态栏图标上。要利用此属性,必须在第一次创建通知时设为1。(如果只是在更新通知时才把此值从0改成任意大于0的数,则数字不会显示出来。)

iconLevel属性

表示通知图标当前的LevelListDrawable等级。通过改变这个值,可以在状态栏中显示图标的动画,这个值与LevelListDrawable中drawable的定义相关。详情请参阅LevelListDrawable

程序能自定义更多特性,详情请参阅Notification

创建自定义的展开View

默认情况下,通知窗口中的展开视图(view)包括基本的标题和文本信息。这是由setLatestEventInfo() contentTitlecontentText参数指定的。不过仍可以用RemoteViews来自定义一个展开视图的布局。右侧的截图就展示了一个自定义展开视图的例子,其中用到了LinearLayout 布局中的ImageView和TextView。

要自定义展开信息的布局,需要实例化一个RemoteViews对象,并将它传递给Notification的contentView属性,同时把PendingIntent传给contentIntent属性。

通过例子是对创建自定义展开视图最好的理解方式:

1. 为展开视图新建XML布局,建立一个名为custom_notification_layout.xml的布局文件,内容如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 

              android:orientation="horizontal" 

              android:layout_width="fill_parent" 

              android:layout_height="fill_parent" 

              android:padding="3dp" 

              > 

    <ImageView android:id="@+id/image" 

              android:layout_width="wrap_content" 

              android:layout_height="fill_parent" 

              android:layout_marginRight="10dp" 

              /> 

    <TextView android:id="@+id/text" 

              android:layout_width="wrap_content" 

              android:layout_height="fill_parent" 

              android:textColor="#000" 

              /> 

</LinearLayout>

此布局用于展开视图,但ImageView和TextView的内容还需要由应用程序来定义。RemoteViews提供了一些方便的方法来定义这些内容。

2. 在应用程序代码里,用RemoveViews的方法来定义图片和文字。然后把RemoteViews对象传给Notification的contentView属性,如下所示:

RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout); 

contentView.setImageViewResource(R.id.image, R.drawable.notification_image); 

contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view"); 

notification.contentView = contentView;

如上:先把程序package名和布局资源ID传给RemoteViews的构造方法。然后用setImageViewResource()setTextViewText()定义ImageViewTextView的内容,分别把View对象的资源ID、所赋的内容作为参数传入。最后,把RemoteViews对象传给NotificationcontentView属性。

3. 由于自定义视图不需要执行setLatestEventInfo()方法,因此必须用contentIntent属性来定义一个通知所要执行的意图Intent ,如下:

Intent notificationIntent = new Intent(this, MyClass.class); 

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 

notification.contentIntent = contentIntent;

4. 现在通知可以如常发送了:

mNotificationManager.notify(CUSTOM_VIEW_ID, notification);

RemoteViews类还包含了一些方法,便于在通知的展开视图里增加ChronometerProgressBar关于用RemoteViews创建自定义布局的详细信息,请参阅RemoteViews 类的参考文档。

注意:当建立一个自定义展开视图时,必须特别小心,保证自定义的布局能正常工作在不同的设备方向和分辨率下。这个建议对于所有在Android上创建的View布局都是适用的,但在这种情况下尤为重要,因为布局实际可用的屏幕区域非常有限。不要把自定义布局设计得过于复杂,并且一定要在各种环境配置下进行测试。


例如:最常用的就是当接收到新短信时,可以在通知栏里面看到简短的信息。

创建状态栏通知的过程:

1.取得通知管理器

  1. NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE); 

2.实例化通知对象

  1. /** 
  2.  * new Notification(int icon, String message, long when) 
  3.  * 参数1:通知图标 
  4.  * 参数2:简短提示文本 
  5.  * 参数3:何时显示,这里使用的是时间戳 
  6.  */ 
  7. Notification notification = new Notification(R.drawable.icon, "状态栏通知测试", System.currentTimeMillis()); 

3.定义通知的详细信息、及PendIntent来设置激活的Activity

  1. //这里设置意图处理很简单,仅仅是当用户触摸详细信息时,将会显示MainActivity界面 
  2.         Intent notificationIntent = new Intent(this, MainActivity.class); 
  3.         PendingIntent pendingIntent = PendingIntent.getActivity(this200, notificationIntent, 0); 
  4.         notification.setLatestEventInfo(this"通知完整标题""通知内容", pendingIntent); 

4.传递到通知管理器,加入到通知队列

  1. manager.notify(11, notification); 

这样,就完成了一个简单的状态栏通知。

除此之外,还可以设置通知的提示方式,如震动、音乐、闪烁等。

设置提示声音:

  1. notification.sound = Uri.parse("file:///sdcard/On Call.mp3"); 

设置震动的交替模式:

  1. notification.vibrate  = new long[]{0,100,200,300}; 

这里vibrate是一个长整型数组,用来设置震动交替时长,第一个值表示震动开始之前,第二个值表示第一次震动的时间,第三个值表示第二次震动的时间,以次类推。






(3)Dialog Notification

一个对话框,用于遮挡当前界面,使得当前界面失去焦点。

通常用于锁定屏幕,提示用户等待等场景。例如:某个文件正在下载,出现提示等待。成功下载之后才能允许用户进行其他操作。

常用Dialog类型有:Alert Dialog、ProgressDialog、Custom Dialog

1.使用AlertDialog创建选择窗口、列表窗口、单选窗口、多选窗口

1.1选择窗口

创建弹窗方法:

  1.     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  2.     builder.setCancelable(false);//设置当点击返回按钮后,默认表示的行为。这里设置为false 
  3.     builder.setMessage("dialog弹窗标题"); 
  4.      
  5.     //设置true按钮 
  6.     builder.setPositiveButton("Yes"new OnClickListener() { 
  7.     @Override 
  8.     public void onClick(DialogInterface dialog, int which) { 
  9.         Toast.makeText(getApplicationContext(), "您选择了Yes", Toast.LENGTH_LONG).show(); 
  10.     } 
  11. }); 
  12.      
  13.     //设置false按钮 
  14.     builder.setNegativeButton("No"new OnClickListener() { 
  15.     @Override 
  16.     public void onClick(DialogInterface dialog, int which) { 
  17.         dialog.cancel(); 
  18.     } 
  19. }); 
  20.      
  21.     //显示 
  22.     builder.show(); 

1.2列表窗口

创建方法:

  1.     final String[] list = new String[]{"item1""item2""item3"}; 
  2.      
  3.     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  4.     builder.setTitle("dialog list弹窗标题"); 
  5.     /** 
  6.      * setItems(CharSequence[] items, OnClickListener listener) 
  7.      * items:接收字符串数组,作为下拉列表选项 
  8.      * listener:监听选中事件 
  9.      */ 
  10.     builder.setItems(list, new OnClickListener() { 
  11.  
  12. @Override 
  13. /** 
  14.  * dialog:表示当前弹窗对象 
  15.  * which:表示当前选中项的对应list数组的序号 
  16.  */ 
  17. public void onClick(DialogInterface dialog, int which) { 
  18.     Toast.makeText(getApplicationContext(), "您选择了:"+list[which], Toast.LENGTH_LONG).show(); 
  19. ); 
  20.      
  21.     builder.show(); 

1.3单选列表弹窗

创建方法:

  1.     final String[] list = new String[]{"item1""item2""item3"}; 
  2.      
  3.     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  4.     builder.setTitle("dialog list_single弹窗标题"); 
  5.     /** 
  6.      * setSingleChoiceItems(CharSequence[] items, int checkedItem, OnClickListener listener) 
  7.      * items:下拉列表字符串数组 
  8.      * checkedItem:默认选中的数组序号,-1表示没有默认选中项 
  9.      * listener:监听选中事件,注意!,单选、多选弹窗,当选择某个项时,默认是不会关闭弹窗的。需要手动关闭。 
  10.      */ 
  11.     builder.setSingleChoiceItems(list, -1new OnClickListener() { 
  12.      
  13.     @Override 
  14.     public void onClick(DialogInterface dialog, int which) { 
  15.         Toast.makeText(getApplicationContext(), list[which], Toast.LENGTH_SHORT).show(); 
  16.         dialog.cancel(); 
  17.         //这里,当用户选中某个项时,提示选中文字,并关闭弹窗 
  18.     } 
  19. }); 
  20.      
  21.     builder.show(); 

1.4多选列表弹窗

创建方法:

  1.     final String[] list = new String[]{"item1""item2""item3"}; 
  2.      
  3.     AlertDialog.Builder builder = new AlertDialog.Builder(this); 
  4.     builder.setTitle("dialog list_mutil弹窗标题"); 
  5.     /** 
  6.      * setMultiChoiceItems(CharSequence[] items, boolean[] checkedItems, OnMultiChoiceClickListener listener) 
  7.      * items:下拉列表字符串数组 
  8.      * checkedItems:boolean数组,如果需要默认被选中,可以传递。null表示没有默认选中项 
  9.      * listener:监听选中事件,注意!,单选、多选弹窗,当选择某个项时,默认是不会关闭弹窗的。需要手动关闭。 
  10.      */ 
  11. builder.setMultiChoiceItems(list, nullnew OnMultiChoiceClickListener() { 
  12.      
  13.     @Override 
  14.     public void onClick(DialogInterface dialog, int which, boolean isChecked) { 
  15.         Toast.makeText(getApplicationContext(), list[which], Toast.LENGTH_SHORT).show(); 
  16.         dialog.cancel(); 
  17.     } 
  18. }); 
  19.  
  20. builder.show(); 

2、自定义弹窗

如果需要自定义弹窗外观,那么可以使用自定义弹窗。

下面一个自定义弹窗效果,并看看是如何实现的。

  1. AlertDialog.Builder builder; 
  2. LayoutInflater inflater = getLayoutInflater(); 
  3. View layout = inflater.inflate(R.layout.custom_dialog, (ViewGroup)findViewById(R.id.layout_root)); 
  4.  
  5. TextView text = (TextView) layout.findViewById(R.id.text); 
  6. text.setText("这是自定义弹窗"); 
  7.  
  8. builder = new AlertDialog.Builder(getApplicationContext()); 
  9. builder.setView(layout); 
  10. builder.show(); 

实际上自定义弹窗,就是使用自定义界面并覆盖原有视图内容。

0 0