- android
- android.accessibilityservice
- android.accounts
- android.content
- android.database.sqlite
- android.graphics
- android.location
- android.media
- android.net
- android.os
- android.text
- android.view
- android.view.inputmethod
- android.widget
- AbsListView
- AbsoluteLayout
- AbsSeekBar
- AbsSpinner
- AdapterView
- AnalogClock
- BaseAdapter
- BaseExpandableListAdapter
- Button
- CheckBox
- CheckedTextView
- Checkable
- Chronometer
- CompoundButton
- CursorAdapter
- CursorTreeAdapter
- DatePicker
- DialerFilter
- DigitalClock
- EditText
- Filter
- Filter.FilterListener
- Filter.FilterResults
- ExpandableListAdapter
- Filterable
- Gallery
- Gallery.LayoutParams
- GridView
- GridLayout
- RadioGroup
- ImageView
- HorizontalScrollView
- ImageButton
- ImageSwitcher
- FilterQueryProvider
- ListAdapter
- ListView
- MediaController
- QuickContactBadge
- RadioButton
- RatingBar
- RelativeLayout
- RemoteViews
- ResourceCursorAdapter
- ResourceCursorTreeAdapter
- Scroller
- ScrollView
- SearchView
- SeekBar
- SeekBar.OnSeekBarChangeListener
- SimpleAdapter
- SimpleCursorAdapter
- SimpleCursorTreeAdapter
- SimpleExpandableListAdapter
- SlidingDrawer
- Spinner
- SpinnerAdapter
- WrapperListAdapter
- TabHost
- TabHost.TabSpec
- TextView
- TimePicker
- Toast
- TableLayout
- TableRow
- TableRow.LayoutParams
- TabWidget
- TextSwitcher
- ToggleButton
- TwoLineListItem
- VideoView
- ViewAnimator
- ViewFlipper
- ViewSwitcher
- ZoomButtonsController
- ZoomButton
- ZoomControls
- dalvik.system
状态栏通知
状态栏通知
译者微博: http://weibo.com/popapa
版本:Android 4.0 r1
原文
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
快速查看
· 状态栏(status bar)通知允许应用程序以不干扰当前 activity 的方式将事件通知用户。
· 可以给通知绑定一个意图(intent),当用户点击时系统会执行此意图。
在本文中
关键类
状态栏(status bar)通知将一个图标填加到系统的状态栏中(包含一条可选的提示文本信息),并将一条展开信息添加到通知窗口中。当用户选中展开信息时,Android 将执行一个此通知已定义的意图 Intent (通常用于弹出一个 Activity )。你还可以对通知进行配置,用设备提供的声音、振动、闪光来提醒用户。
当后台服务(Service)需要对某个事件发出提醒并且需要用户响应时,状态栏通知就能发挥作用了。后台服务 从来不会 启动 Activity 来接收用户的交互,取而代之的是应该创建一个状态栏通知,在用户点选后再由通知来启动 Activity。
以下截图展示了一个左侧带有通知图标的状态栏:
下图展示了“Notifications”窗口内的通知展开信息。用户可通过下拉状态栏(或在 Home 菜单里选中 通知 )来显示这个通知窗口。
基础知识
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、展开信息的标题和文本外,可以利用对象的成员值修改每个属性。要修改通知的文本信息,只能对 contentTitle 和 contentText 参数赋新值并调用 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)包括基本的标题和文本信息。这是由 setLatestEventInfo() 的 contentTitle 和 contentText 参数指定的。不过仍可以用 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() 定义 ImageView 和 TextView 的内容,分别把 View 对象的资源 ID、所赋的内容作为参数传入。最后,把 RemoteViews 对象传给 Notification 的 contentView 属性。
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 类还包含了一些方法,便于在通知的展开视图里增加 Chronometer 或 ProgressBar 。关于用 RemoteViews 创建自定义布局的详细信息,请参阅 RemoteViews 类的参考文档。
注意: 当建立一个自定义展开视图时,必须特别小心,保证自定义的布局能正常工作在不同的设备方向和分辨率下。这个建议对于所有在 Android 上创建的 View 布局都是适用的,但在这种情况下尤为重要,因为布局实际可用的屏幕区域非常有限。不要把自定义布局设计得过于复杂,并且一定要在各种环境配置下进行测试。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论