通知欄提示 Status Bar Notifications

前言

  本章內容爲Android開發者指南的 Framework Topics/User Interface/Notifications/Status Bar Notifications章節,譯爲"狀態欄通知",版本爲Android 4.0 r1,翻譯來自:"呆呆大蝦",歡迎訪問他的微博:"http://weibo.com/popapa",再次感謝"呆呆大蝦" !期待你一起參與翻譯Android的相關資料,聯繫我[email protected]

 

聲明

  歡迎轉載,但請保留文章原始出處:) 

    博客園:http://www.cnblogs.com/

    Android中文翻譯組:http://androidbox.sinaapp.com/

 

 

狀態欄通知

譯者署名: 呆呆大蝦

譯者微博:http://weibo.com/popapa

版本:Android 4.0 r1

原文

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

 

快速查看

·            狀態欄(status bar)通知允許應用程序以不干擾當前activity的方式將事件通知用戶。

·            可以給通知綁定一個意圖(intent),當用戶點擊時系統會執行此意圖。

在本文中

基礎知識

管理通知

創建通知

更新通知

添加聲音

添加振動

添加閃光

其他特性

創建自定義的展開View

關鍵類

Notification

NotificationManager

 

狀態欄(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在整個應用程序範圍內唯一標識NotificationNotification需要更新;應用程序可能管理着多種不同的通知,在用戶通過各自定義的Intent返回應用程序時必須能選擇正確的動作執行之,因此上述參數是必需的。

要實現用戶從通知窗口內點選後自動清除狀態欄通知,請在Notification對象中加入“FLAG_AUTO_CANCEL”標誌。也可以傳入通知IDcancel(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");

這時,已知有資源ID6的媒體文件,並且已添加到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等級。通過改變這個值,可以在狀態欄中顯示圖標的動畫,這個值與LevelListDrawabledrawable的定義相關。詳情請參閱LevelListDrawable

程序能自定義更多特性,詳情請參閱Notification

 

 

創建自定義的展開View

默認情況下,通知窗口中的展開視圖(view)包括基本的標題和文本信息。這是由setLatestEventInfo() contentTitlecontentText參數指定的。不過仍可以用RemoteViews來自定義一個展開視圖的佈局。右側的截圖就展示了一個自定義展開視圖的例子,其中用到了LinearLayout 佈局中的ImageViewTextView

 

要自定義展開信息的佈局,需要實例化一個RemoteViews對象,並將它傳遞給NotificationcontentView屬性,同時把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>

此佈局用於展開視圖,但ImageViewTextView的內容還需要由應用程序來定義。RemoteViews提供了一些方便的方法來定義這些內容。

 

2.         在應用程序代碼裏,用RemoveViews的方法來定義圖片和文字。然後把RemoteViews對象傳給NotificationcontentView屬性,如下所示:

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佈局都是適用的,但在這種情況下尤爲重要,因爲佈局實際可用的屏幕區域非常有限。不要把自定義佈局設計得過於複雜,並且一定要在各種環境配置下進行測試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章