【Android】狀態列通知Notification、NotificationManager詳解

encienqi發表於2012-07-28

在訊息通知時,我們經常用到兩個元件Toast和Notification。特別是重要的和需要長時間顯示的資訊,用Notification就最合適不過了。當有訊息通知時,狀態列會顯示通知的圖示和文字,通過下拉狀態列,就可以看到通知資訊了,Android這一創新性的UI元件贏得了使用者的一致好評,就連蘋果也開始模仿了。今天我們就結合例項,探討一下Notification具體的使用方法。

首先說明一下我們需要實現的功能是:在程式啟動時,發出一個通知,這個通知在軟體執行過程中一直存在,相當於qq的托盤一樣;然後再演示一下普通的通知和自定義檢視通知。

那我們就先建立一個名為notification的專案,然後編輯/res/layout/main.xml檔案,程式碼如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.     <TextView  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:gravity="center"  
  10.         android:text="點選按鈕進入演示介面"/>  
  11.     <Button  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:text="notify activity"  
  15.         android:onClick="notify"/>  
  16. </LinearLayout>  

然後編輯MainActivity.java檔案,程式碼如下:

[java] view plaincopy
  1. package com.scott.notification;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11.   
  12. public class MainActivity extends Activity {  
  13.   
  14.     private static final int ONGOING_ID = 0;  
  15.     private NotificationManager mNotificationManager;  
  16.       
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.main);  
  21.         setUpNotification();  
  22.     }  
  23.   
  24.     private void setUpNotification() {  
  25.         Context context = this;  
  26.   
  27.         mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  28.   
  29.         int icon = R.drawable.ongoing;  
  30.         CharSequence tickerText = "程式已啟動";  
  31.         long when = System.currentTimeMillis();  
  32.           
  33.         //新建一個Notification例項  
  34.         Notification notification = new Notification(icon, tickerText, when);  
  35.   
  36.         // 把通知放置在"正在執行"欄目中  
  37.         notification.flags |= Notification.FLAG_ONGOING_EVENT;  
  38.   
  39.         CharSequence contentTitle = "Notification示例";  
  40.         CharSequence contentText = "程式正在執行中,點選此處跳到演示介面";  
  41.           
  42.         Intent intent = new Intent(context, NotifyActivity.class);  
  43.         PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  44.   
  45.         notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);  
  46.   
  47.         mNotificationManager.notify(ONGOING_ID, notification);  
  48.     }  
  49.   
  50.     public void notify(View view) {  
  51.         Intent intent = new Intent(this, NotifyActivity.class);  
  52.         startActivity(intent);  
  53.     }  
  54.       
  55.     @Override  
  56.     public void onBackPressed() {  
  57.         super.onBackPressed();  
  58.         finish();  
  59.         //取消一個通知  
  60.         mNotificationManager.cancel(ONGOING_ID);  
  61.         //結束程式  
  62.         android.os.Process.killProcess(android.os.Process.myPid());  
  63.         System.exit(0);  
  64.     }  
  65. }  

大家看以看到,在程式主介面啟動時會發出一個通知,並且將這個通知放置在“正在執行”欄目中,這樣在軟體執行過程中它就會始終存在;另外,在上面的程式碼中,在使用者按下回退按鈕時,我們使用NotificationManager.cancel(int id)方法取消這個通知。

先來看一下執行效果如何:

 

 

點選主介面的按鈕和Ongoing欄目中的通知均能跳轉到NotifyActivity介面,在這個介面中,我們主要演示一下普通通知和自定義檢視通知的使用。

我們先要在/res/layout/目錄下新增一個notify.xml佈局檔案,程式碼如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent">  
  6.     <Button  
  7.         android:layout_width="fill_parent"  
  8.         android:layout_height="wrap_content"  
  9.         android:text="normal notify"  
  10.         android:onClick="normalNotify"/>  
  11.     <Button  
  12.         android:layout_width="fill_parent"  
  13.         android:layout_height="wrap_content"  
  14.         android:text="custom notify"  
  15.         android:onClick="customNotify"/>  
  16. </LinearLayout>  

因為要演示自定義通知檢視,我們需要定義一個自定義通知檢視的佈局檔案,擺放我們自己的佈局元件,因此在/res/layout/目錄下新增一個custom_notification_layout.xml檔案,程式碼如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.   android:orientation="horizontal"  
  4.   android:layout_width="fill_parent"  
  5.   android:layout_height="fill_parent"  
  6.   android:padding="3dp">  
  7.   <ImageView  
  8.     android:id="@+id/imageView"  
  9.     android:layout_width="wrap_content"  
  10.     android:layout_height="fill_parent"  
  11.     android:layout_marginRight="10dp"/>  
  12.   <TextView   
  13.     android:id="@+id/textView"           
  14.     android:layout_width="wrap_content"                
  15.     android:layout_height="fill_parent"                
  16.     android:textColor="#000"/>  
  17. </LinearLayout>  

然後就來看一下NotifyActivity.java的程式碼:

[java] view plaincopy
  1. package com.scott.notification;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.widget.RemoteViews;  
  12.   
  13. public class NotifyActivity extends Activity {  
  14.       
  15.     //注意,如果不想覆蓋前一個通知,需設定不同的ID  
  16.     private static final int NORMAL_NOTIFY_ID = 1;  
  17.     private static final int CUSTOM_NOTIFY_ID = 2;  
  18.       
  19.     @Override  
  20.     protected void onCreate(Bundle savedInstanceState) {  
  21.         super.onCreate(savedInstanceState);  
  22.         setContentView(R.layout.notify);  
  23.     }  
  24.       
  25.     // 普通通知事件  
  26.     public void normalNotify(View view) {  
  27.         Context context = this;  
  28.   
  29.         NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  30.   
  31.         int icon = android.R.drawable.stat_notify_voicemail;  
  32.         CharSequence tickerText = "普通通知";  
  33.         long when = System.currentTimeMillis();  
  34.         Notification notification = new Notification(icon, tickerText, when);  
  35.   
  36.         // 設定聲音  
  37.         notification.defaults |= Notification.DEFAULT_SOUND;  
  38.           
  39.         //設定震動(需加VIBRATE許可權)  
  40.         notification.defaults |= Notification.DEFAULT_VIBRATE;  
  41.           
  42.         // 設定LED燈提醒  
  43.         notification.defaults |= Notification.DEFAULT_LIGHTS;  
  44.           
  45.         // 設定點選此通知後自動清除  
  46.         notification.flags |= Notification.FLAG_AUTO_CANCEL;  
  47.   
  48.         CharSequence contentTitle = "普通通知的標題";  
  49.         CharSequence contentText = "通知的內容部分,一段長長的文字...";  
  50.         Intent intent = new Intent(context, TargetActivity.class);  
  51.         PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  52.   
  53.         notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);  
  54.   
  55.         mNotificationManager.notify(NORMAL_NOTIFY_ID, notification);  
  56.     }  
  57.   
  58.     // 個性化通知點選事件  
  59.     public void customNotify(View view) {  
  60.         Context context = this;  
  61.   
  62.         NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  63.   
  64.         int icon = android.R.drawable.stat_notify_voicemail;  
  65.         CharSequence tickerText = "自定義通知";  
  66.         long when = System.currentTimeMillis();  
  67.         Notification notification = new Notification(icon, tickerText, when);  
  68.   
  69.         notification.flags |= Notification.FLAG_AUTO_CANCEL;  
  70.   
  71.         RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.custom_notification_layout);  
  72.         contentView.setImageViewResource(R.id.imageView, R.drawable.smile);  
  73.         contentView.setTextViewText(R.id.textView, "這是一個個性化的通知檢視,代替了系統預設的通知檢視.");  
  74.         // 指定個性化檢視  
  75.         notification.contentView = contentView;  
  76.   
  77.         Intent intent = new Intent(context, TargetActivity.class);  
  78.         PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  79.         // 指定內容意圖  
  80.         notification.contentIntent = contentIntent;  
  81.   
  82.         mNotificationManager.notify(CUSTOM_NOTIFY_ID, notification);  
  83.     }  
  84. }  

注意,上邊在新增一個普通通知時使用到了震動,所以需要在AndroidManifest.xml中加入相關許可權:

[html] view plaincopy
  1. <uses-permission android:name="android.permission.VIBRATE"/>  

除了使用程式碼中的預設通知屬性之外,使用者也可以自定義屬性值:

1.自定義聲音:

[java] view plaincopy
  1. notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");  

2.自定義震動方式:

[java] view plaincopy
  1. long[] vibrate = {0100200300};  
  2. notification.vibrate = vibrate;  

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

3.自定義閃光方式:

[java] view plaincopy
  1. notification.ledARGB = 0xff00ff00;  
  2. notification.ledOnMS = 300;  
  3. notification.ledOffMS = 1000;  
  4. notification.flags |= Notification.FLAG_SHOW_LIGHTS;  

上邊幾行程式碼表示綠燈先顯示300毫秒然後關閉一秒鐘。如果裝置不支援指定的顏色,則會按照最接近的顏色顯示。

如果全部都使用預設值時,可以用以下程式碼代替程式中的幾行設定defaults的程式碼:

[java] view plaincopy
  1. notification.defaults |= Notification.DEFAULT_ALL;  

注意,在自定義以上屬性時,如果defaults中與之相關的預設值已設定,則自定義屬性就會失效。

然後再來介紹一下幾種常用的flags:

1.FLAG_AUTO_CANCEL:在使用者檢視通知資訊後自動關閉通知;

2.FLAG_INSISTENT:在使用者響應之前一直重複;

3.FLAG_ONGOING_EVENT:放置在“正在執行”欄目中,表示程式正在執行,可見狀態,或是後臺執行;

4.FLAG_NO_CLEAR:檢視通知後不會自動取消,對一直進行中的通知非常有用。

在上面的程式中,點選通知後跳轉到TargetActivity介面,這個介面非常簡單,就顯示一串文字,這裡就不必多說了。

最後讓我們演示一下效果:

關於notification的相關知識,今天先介紹到這裡,以後會繼續介紹更深入的使用技巧。

相關文章