通知狀態列(status bar notification)是一個包含圖片和通知資訊加上可選的ticker-text資訊,當使用者選擇的時候,android系統會開啟一個意圖intent(通常是啟動一個activity).你當然可以設定以鈴聲,震動,燈光等來通知使用者。
狀態通知欄應該發生在當後台服務程式想提醒需要使用者相應的事件,android建議開發這,後台服務程式不應該在需要與使用者互動的時候直接啟動一個活動介面,你的背景程式應該建立一個狀態通知,使用者可以選擇這個通知來啟動某個活動介面。activity和service都可以組建通知,但是你會通常在service裡執行個體化它。這個時候你需要用到兩個類:Notification and NotificationManager。
Notification定義的是通知的屬性,而NotificationManager是android系統執行和管理狀態列中所有的通知。NotificationManager只能通過getSystemService()執行個體化,通過notify()來傳遞某個Notification執行個體。
建立你的Notification:
建立一個Notification需要一張出現在狀態列裡圖片,標題於資訊(除非你自訂status bar),一個意圖(使用者選擇時候出發)。還有幾個是可選的:ticker-text(至於這個提示資訊,就是通知剛出現的時候跟圖表一起出現的資訊,稍後就會和通知的表徵圖自動消失),聲音,震動設定,燈光。基本的執行個體化一個notification代碼如下:
1 int icon = R.drawable.notification_icon; // icon from resources
2 CharSequence tickerText = "Hello"; // ticker-text
3 long when = System.currentTimeMillis(); // notification time
4 Context context = getApplicationContext(); // application Context
5 CharSequence contentTitle = "My notification"; // message title
6 CharSequence contentText = "Hello World!"; // message text
7
8 Intent notificationIntent = new Intent(this, MyClass.class);
9 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
10
11 // the next two lines initialize the Notification, using the configurations above
12 Notification notification = new Notification(icon, tickerText, when);
13 notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
管理你的通知:
先實得到notificationmanager一個引用,代碼如下:
1 String ns = Context.NOTIFICATION_SERVICE;
2 NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
當你想傳遞你的notification的時候,你需要使用notify(int , Notification)函數,這裡的第一個參數很重要,就是你這個notification 在這個應用程式的唯一標識,當你需要更新你的通知(或許你的狀態列裡的通知不止一個)或者使用者飯回到你的應用(通過你在通知裡定義的意圖)時候你判斷執行什麼樣的動作。
清除通知非常簡單。你可以在定義你的Notification的時候添加"Flag_auto_cancel",你同樣可以傳遞你的notification的id調用cancel(int),或者你可以試試cancelAll().
對通知添加聲音,震動,燈光等就不細講了,下面主要說說自訂通知。
預設情況下,包含標題和資訊的通知會出現在你的通知視窗裡。但是你也可以使用RemoteViews類來自訂一個layout顯示你的通知。
首先,你得現定義你的通知布局檔案,你自己隨便定義一個custom_notification_layout.xml:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView android:id="@+id/textview"
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content"/>
10 <ProgressBar android:id="@+id/progress_bar"
11 style="@android:style/Widget.ProgressBar.Horizontal"
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:max="100"/>
15 </LinearLayout>
這個時候,你需要用到RemoteViews這個類來infalte這個layout檔案。RemoteViews是一個描述了一個可以在另一個進程中顯示的視圖階層,並且提供了一些操作方法。設定完你remoteview之後,你就把它賦值給你的notification的contentView這個屬性就可以了。下面是我些的一個service類,產生一個線程自動更新progressbar的值來提示給使用者:
1 public class LocalService extends Service {
2 NotificationManager nManager = null;
3 Context context = null;
4 Notification notification = null;
5 private MyThread thread = null;
6 private static final int HELLO_ID = 1;
7 @Override
8 public void onCreate() {
9 // TODO Auto-generated method stub
10 Log.e("localservcie :------>", "onCreate");
11 context = getApplicationContext();
12 nManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
13
14 int icon = R.drawable.ic_launcher;
15 CharSequence tickerText = "通知";
16 long when = System.currentTimeMillis();
17 notification = new Notification();
18 notification.when = when;
19 notification.tickerText =tickerText;
20 notification.icon = icon;
21 super.onCreate();
22 }
23
24 @Override
25 public void onLowMemory() {
26 // TODO Auto-generated method stub
27 Log.e("localservcie :------>", "onLowMemory");
28 thread.stopThread();
29 nManager.cancel(HELLO_ID);
30 super.onLowMemory();
31 }
32
33 @Override
34 public void onDestroy() {
35 Log.e("localservcie :------>", "onDestroy");
36 thread.stopThread();
37 nManager.cancel(HELLO_ID);
38 super.onDestroy();
39 }
40
41 @Override
42 public void onRebind(Intent intent) {
43 // TODO Auto-generated method stub
44 super.onRebind(intent);
45 }
46
47 @Override
48 public int onStartCommand(Intent intent, int flags, int startId) {
49 // TODO Auto-generated method stub
50 Log.e("localservcie :------>", "onStartCommand");
51
52 thread = new MyThread();
53 thread.startThread();
54 return super.onStartCommand(intent, flags, startId);
55 }
56 @Override
57 public IBinder onBind(Intent intent) {
58 // TODO Auto-generated method stub
59 return null;
60 }
61 @Override
62 public boolean onUnbind(Intent intent) {
63 // TODO Auto-generated method stub
64 return super.onUnbind(intent);
65 }
66
67 private void update(int value){
68 RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
69 contentView.setTextViewText(R.id.textview, "xia zai ren wu 1");
70 contentView.setProgressBar(R.id.progress_bar, 100, value, false);
71 notification.contentView = contentView;
72 Intent notificationIntent = new Intent(context,NotificationActivity.class);
73 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
74 notification.contentIntent = pendingIntent;
75 nManager.notify(HELLO_ID, notification);
76 }
77
78 class MyThread implements Runnable{
79 private volatile Thread runner;
80
81 public synchronized void startThread(){
82 if(runner == null){
83 runner = new Thread(this);
84 runner.start();
85 }
86 }
87
88 public synchronized void stopThread(){
89 if(runner != null){
90 Thread moribund = runner;
91 runner = null;
92 moribund.interrupt();
93 }
94 }
95
96 public void run(){
97 while(Thread.currentThread() == runner){
98 //do stuff which can be interrupted if necessary
99 int value =10;
100 while(value<=100){
101 try {
102 Log.e("localservice->thread->run()", "run");
103 update(value);
104 Thread.sleep(1000);
105 value+=10;
106
107 } catch (InterruptedException e) {
108 Log.e("localservice->thread->run()", "InterruptedException");
109 return;
110 }
111 }
112 }
113 }
114
115 }
116
117
118 }
如下: