創建狀態欄通知 notification

懶骨頭(http://blog.csdn.com/iamlazybone

一個狀態欄通知,會在系統的狀態欄添加一個圖標,並且在狀態窗口添加一條信息。當用戶點擊這個信息時,android會發送一個intent請求,通常是啓動一個已定義的activity。你可以添加聲音、震動、閃屏給設備來提醒用戶。

通常一個後臺服務運行時,如果需要提醒用戶一些事件、或者讓用戶反饋一些信息時,通常用到狀態欄提醒。一個後臺Service永遠不會自己運行一個activity來接受用戶交互,一般的,後臺服務會添加一個狀態欄通知來與用戶進行交互。

下圖顯示了一個狀態欄通知:

 

接下來的會顯示狀態欄窗口。用戶可以打開這個窗口通過下滑狀態欄。或者使用menu菜單鍵選擇。

 


--------------------------------------------------------------------------------

基礎知識

一個activity或者Service可以初始化狀態欄通知,因爲activity只有在活動狀態下才能執行一些命令,所以你需要從一個service來建立狀態通知。當用戶啓動了其他程序或者設備已經休眠時,通過這種方式,通知就可以在後臺被創建。你要用到這兩個類:Notification類和NotificationManager類。

Notification類來定義狀態通知的屬性,比如圖標,提示信息,或者提示聲音。NotificationManager是一個android系統的服務,來管理和運行所有通知的,他不能被實例化,你可以用getSystemService()方法獲得他的句柄。當你想通知用戶時,調用notify()方法即可。

創建一個菜單欄通知:

1-獲得MotificationManager的引用。

view plaincopy to clipboardprint?
01.String ns = Context.NOTIFICATION_SERVICE;  
02.NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); 
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

2-實例化Notification:

view plaincopy to clipboardprint?
01.int icon = R.drawable.notification_icon;  
02.CharSequence tickerText = "Hello";  
03.long when = System.currentTimeMillis();  
04.Notification notification = new Notification(icon, tickerText, when); 
int icon = R.drawable.notification_icon;
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);

3-定義Notification,如顯示icon、目標intent等信息

view plaincopy to clipboardprint?
01.Context context = getApplicationContext();  
02.CharSequence contentTitle = "My notification";  
03.CharSequence contentText = "Hello World!";  
04.Intent notificationIntent = new Intent(this, MyClass.class);  
05.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
06.notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
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-傳遞給Manager.

view plaincopy to clipboardprint?
01.private static final int HELLO_ID = 1;  
02.mNotificationManager.notify(HELLO_ID, notification); 
private static final int HELLO_ID = 1;
mNotificationManager.notify(HELLO_ID, notification);

好了,一個通知寫完了。


--------------------------------------------------------------------------------

管理你的通知

NotificationManager是一個管理所有通知的系統服務。你可以通過getSystemService()方法得到她的句柄:

view plaincopy to clipboardprint?
01.String ns = Context.NOTIFICATION_SERVICE;  
02.NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); 
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);

當你想發送一個狀態欄通知時,通過notify(int,Notification)方法傳遞Notification對象給NotificationManager,第一個參數是Notification的id,第二個參數是通知的對象。id是一個唯一的標示,當你改變通知或者進行一些的活動時必須要用到它。

當用戶從通知窗口選擇了某個通知時,會給這個通知添加一個“FLAG_AUTO_CANCEL”標記來移除這個通知。你也可以使用cancel(int)方法,通過指定通知id來取消某個通知,或者乾脆cancelAll()。


--------------------------------------------------------------------------------

 建立一個通知

一個通知對象定義了顯示在狀態欄的一些細節信息,和所有通知方式,例如聲音、閃光。

一個狀態欄通知必須包括以下幾點:

@ 顯示在狀態欄的圖標

@ 一個標題(除非你自定義了提示界面)

@ 一個Pending Intent,即點擊後要做的操作。

可選項包括以下:

@ 狀態欄提示文本

@ 提示聲音

@ 震動

@ 閃光

初學者套件?爲新的通知包含了MNotification(int,CharSequence,long)構造方法和setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)方法。這些參數是一個通知的必要參數。下面的代碼片段是一個簡單的例子:

view plaincopy to clipboardprint?
01.int icon = R.drawable.notification_icon;        // icon from resources  
02.CharSequence tickerText = "Hello";              // ticker-text  
03.long when = System.currentTimeMillis();         // notification time  
04.Context context = getApplicationContext();      // application Context  
05.CharSequence contentTitle = "My notification";  // expanded message title  
06.CharSequence contentText = "Hello World!";      // expanded message text  
07.Intent notificationIntent = new Intent(this, MyClass.class);  
08.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
09.// the next two lines initialize the Notification, using the configurations above  
10.Notification notification = new Notification(icon, tickerText, when);  
11.notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
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);

更新通知

你可以在事件改變時修改狀態欄的通知。例如,當有一條未讀短信時又來了一條短信,此時狀態欄應該顯示新的短信。像這種情況下,添加一條洗得通知不如更改原有通知更加合理,因爲後者能避免通知的混亂。

因爲每個通知都有一個唯一的Id,你可以通過setLatestEventInfo()方法修改通知,然後調用notify()讓其顯示。

你可以修改每個屬性,除了context和下拉狀態欄時顯示的標題和文本。你可以通過setLatestEventInfo()方法給contentTitle和conTentText設置文本信息,然後調用notify()方法來更新通知。(當然了你可以創建自己的佈局文件,那樣的話更新顯示文本就沒有效果了)。

添加聲音

你可以使用默認的聲音來提醒用戶有一個新通知。方法是添加一個“DEFAULT_SOUND”參數。

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_SOUND; 
notification.defaults |= Notification.DEFAULT_SOUND;

如果使用非默認的聲音,需要傳遞一個URI資源引用。例如:

view plaincopy to clipboardprint?
01.notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); 
notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");

下個例子中,音頻文件從MediaStore類中獲取:

view plaincopy to clipboardprint?
01.notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); 
notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");

這種情況下,資源id爲6的音頻文件時已知的,並且已添加到content的URI中。如果你不知道exact ID,你必須在MediaStore中查詢所有可用的資源。參考 Content Providers文檔。

如果你想讓提示聲音一直播放知道用戶響應位置,你可以添加“FLAG_INSISTENT”參數。

注意:如果包含“DEFAULT_SOUND”參數,那麼默認聲音會覆蓋其他的聲音設置。

添加震動

你可以使用默認的震動方式提示用戶:

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_VIBRATE; 
notification.defaults |= Notification.DEFAULT_VIBRATE;

 或者使用自己的振動方式,例如:

view plaincopy to clipboardprint?
01.long[] vibrate = {0,100,200,300};  
02.notification.vibrate = vibrate; 
long[] vibrate = {0,100,200,300};
notification.vibrate = vibrate;

 這個數組定義了交替的震動和關閉,一毫秒爲單位。第一個值是等待多久開始震動,第二個值是第一次震動的時間,第三個是停止震動的時間,以此類推。定義多長時間都行,但是不能設置爲重複。

注意:如果設置了默認,則其他振動方式無效。

添加手機燈閃爍

讓手機閃動LED燈,你可以實現默認的閃動色繪製。或者定義自己的閃動效果。

使用默認的閃光效果,代碼如下:

view plaincopy to clipboardprint?
01.notification.defaults |= Notification.DEFAULT_LIGHTS; 
notification.defaults |= Notification.DEFAULT_LIGHTS;

定義自己的效果,可以設置顏色、定義顯示的時間,一些常用的值如下:

view plaincopy to clipboardprint?
01.notification.ledARGB = 0xff00ff00;  
02.notification.ledOnMS = 300;  
03.notification.ledOffMS = 1000;  
04.notification.flags |= Notification.FLAG_SHOW_LIGHTS; 
notification.ledARGB = 0xff00ff00;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;

在這個例子裏,綠燈先顯示300毫秒然後關閉一秒鐘,設備不是支持所有的顏色,而且不是所有的設備都支持相同顏色。所以設備會按照指定值顯示最接近的顏色。綠色是常見的顏色。

通知的更多特性

你可以添加幾個特性到你的通知中去。下面是一些有用的設置:

"FLAG_AUTO_CANCEL"標記

這個標記會在用戶選擇查看通知窗口後自動關閉通知。

"FLAG_INSISTENT"

在用戶響應之前一直重複

"FLAG_ONGOING_EVENT"

添加這個標記把通知分在“正在運行”組中,說明程序正在運行,或者後臺運行,甚至當程序不可見時,例如播放音樂或者接聽電話時。

"FLAG_NO_CLEAR"

這個標記讓你的通知不會被Clear按鈕所取消。對一直進行中的通知非常有用。

number field

標記表示當前通知所代表的事件數。這個數字顯示在icon之上。如果你打算這樣使用,當通知第一次建立時必須從1開始計數。如果你改變了他的值從0或其他值開始,那麼他將不會顯示。

iconLevel field

這個值指當前icon的LevelListDrawable等級。通過改變這個值,你可以讓狀態欄的icon顯示動畫。

更多詳細的特性和使用方法餐卡Notification類。


--------------------------------------------------------------------------------

建立一個自定義的通知視圖

 

默認情況下,下拉的Notification窗口包含一個標題和文本信息。setLatestEventInfo()有兩個默認的參數contentTitle和contentText 。然而你通過RemoteViews也可以定義自己下拉通知視圖。上賣弄的截圖就顯示了一個自定義佈局的通知視圖,包括一個TextView和ImageView。

定義自己的通知視圖,實例化RemoteViews對象並且傳遞給contentView。給contentIntent字段傳遞PendingIntent值。創建一個自定義的通知視圖最好的理解方法就是寫一個例子:

1-建立xml佈局文件。例如:custom_notification_layout.xml:

view plaincopy to clipboardprint?
01.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android
02.              android:orientation="horizontal" 
03.              android:layout_width="fill_parent" 
04.              android:layout_height="fill_parent" 
05.              android:padding="3dp" 
06.              > 
07.    <ImageView android:id="@+id/image" 
08.              android:layout_width="wrap_content" 
09.              android:layout_height="fill_parent" 
10.              android:layout_marginRight="10dp" 
11.              /> 
12.    <TextView android:id="@+id/text" 
13.              android:layout_width="wrap_content" 
14.              android:layout_height="fill_parent" 
15.              android:textColor="#000" 
16.              /> 
17.</LinearLayout> 
<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提供一些方便的方法來讓你定義content。

2-下面的代碼,使用RemoveViews 的方法定義image和text。然後傳遞RemoteViews 對象給通知的contentView字段。如下:

view plaincopy to clipboardprint?
01.RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);  
02.contentView.setImageViewResource(R.id.image, R.drawable.notification_image);  
03.contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view");  
04.notification.contentView = 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;

就像顯示的那樣,傳遞程序的包名,佈局的資源id給RemoteViews的構造方法。然後,定義ImageView和TextView的content,使用setImageViewResource()和setTextViewText().這種情況下,傳遞你要設置的view對象的引用id。最後把RemoteViews 對象傳遞給contentView。

3-因爲你不需要setLatestEventInfo()了,你必須爲通知定義一個intent,例如:

view plaincopy to clipboardprint?
01.Intent notificationIntent = new Intent(this, MyClass.class);  
02.PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);  
03.notification.contentIntent = contentIntent; 
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;

4-通知可以這樣調用:

view plaincopy to clipboardprint?
01.mNotificationManager.notify(CUSTOM_VIEW_ID, notification); 
mNotificationManager.notify(CUSTOM_VIEW_ID, notification);

RemoteViews 類也包含一些方法讓你輕鬆地添加Chronometer或者ProgressBar在你的通知view裏。

注意:當建立一個自定義的通知view,你必須特別小心自定義的佈局來適用不同設備的分辨率。尤其這種情況下,更要特別的小心,過於複雜的佈局一定要多多測試


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/iamlazybone/archive/2010/10/22/5959598.aspx

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