前言html
本章內容爲Android開發者指南的 Framework Topics/User Interface/Notifications/Status Bar Notifications章節,譯爲"狀態欄通知",版本爲Android 4.0 r1,翻譯來自:"呆呆大蝦",歡迎訪問他的微博:"http://weibo.com/popapa",再次感謝"呆呆大蝦" !期待你一塊兒參與翻譯Android的相關資料,聯繫我over140@gmail.com。java
聲明android
歡迎轉載,但請保留文章原始出處:) 數組
博客園:http://www.cnblogs.com/app
Android中文翻譯組: http://androidbox.sinaapp.com/
狀態欄通知ide
譯者署名: 呆呆大蝦佈局
譯者微博:http://weibo.com/popapa測試
版本:Android 4.0 r1動畫
原文ui
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
默認狀況下,通知窗口中的展開視圖(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佈局都是適用的,但在這種狀況下尤其重要,由於佈局實際可用的屏幕區域很是有限。不要把自定義佈局設計得過於複雜,而且必定要在各類環境配置下進行測試。