Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android開發指南(38) —— Status Bar Notifications

Android開發指南(38) —— Status Bar Notifications

編輯:Android開發實例

前言

  本章內容為Android開發者指南的 Framework Topics/User Interface/Notifications/Status Bar Notifications章節,譯為"狀態欄通知",版本為Android 4.0 r1,翻譯來自:"呆呆大蝦"。

 

 

狀態欄通知

譯者署名: 呆呆大蝦

譯者微博: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在整個應用程序范圍內唯一標識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()定義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布局都是適用的,但在這種情況下尤為重要,因為布局實際可用的屏幕區域非常有限。不要把自定義布局設計得過於復雜,並且一定要在各種環境配置下進行測試。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved