解讀Notification – Android移動開發技術文章_手機開發 Android移動開發教學課程

綜述
    status bar notification添加一個圖標(和一條可選的ticker-text消息)到系統的status bar(狀態條),並且顯示一個notification message(通知消息)在系統的notifications window(消息窗口)中。當用戶選擇瞭消息窗口中的一條消息,Android系統就發出一個通過Notification定義的Intent(通常是用於啟動一個activity)。你也可以通過配置notification以通過聲音、震動或者是設備上的flashing lights(閃光燈)來告知用戶。
    status bar notification用於後臺運行的服務需要告知用於一些事件並且得到用戶的響應的情況下。後臺運行的服務為瞭及時得到用戶的相應不應該自己啟動一個activity。而應該創建一個用戶選擇後可以啟動activity的status bar notification。
    圖一顯示瞭一個左邊包含一個nitification的圖片。
    圖二顯示瞭在notifications window中有的notifications。
基本
    一個Activity 或者是Service可以初始化一個status bar notification。由於一個通常隻有在處於前臺運行並且和用戶交互的時候才能執行操作,因此,我們通常是通過一個service來創建notifications。這時,即使用戶在運行其他的程序或者是設備進入休眠狀態的時候,我們依然可以在後臺創建notifications。要創建一個notification,我們必須要用到兩個類:Notification和NotificationManage。
    用Notification類的實例來定義status bar notification的屬性,例如:status bar notification的圖標、顯示的message(信息)以及額外的設置,例如播放的聲音。NotificationManager是Android的一項系統服務,通過它可以執行和管理所有的status bar notifications。你不能直接實例化NotificationManager這個類。為瞭實現自己的Notification,你必須通過getSystemService()方法獲得NotificationManager,然後,當你想通知用戶的時候,將Notification傳遞給notify()這個方法,這樣就實現瞭自己的status bar notification。
    通過如下步驟來創建一個status bar 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.定義notification要顯示的message和PendingIntent:
         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);
    到這裡,我們就實現瞭一個notification,用戶應該可以收到這個notification瞭。
    這裡我們舉一個實例,方便大傢清楚的瞭解,要實現的效果就是在主Mactivity上顯示一個Button,當按下這個Button時,就發出我們自定義的一個notification,具體步驟如下:
    第一步:新建一個工程,命名為:Notification01;
    第二步:修改佈局文件main.xml,添加一個Button;

    第三步:修改java源文件,代碼如下:

public class Notification01Activity extends Activity { 
    private Button sendBtn; 
    private static final int HELLO_ID = 1; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
         
        sendBtn = (Button)findViewById(R.id.sendBtn); 
         
        String ns = Context.NOTIFICATION_SERVICE; 
        final NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); 
        int icon = R.drawable.notification_icon; 
        CharSequence tickerText = "Notification01"; 
        long when = System.currentTimeMillis(); 
 
        final Notification notification = new Notification(icon, tickerText, when); 
         
        final Context context = getApplicationContext(); 
        final CharSequence contentTitle = "My notification"; 
        final CharSequence contentText = "Notification01!"; 
         
        sendBtn.setOnClickListener(new View.OnClickListener() { 
             
            @Override 
            public void onClick(View v) { 
                // TODO Auto-generated method stub  
 
                Intent notificationIntent = new Intent(Notification01Activity.this, Notification01Activity.class); 
                PendingIntent contentIntent = PendingIntent.getActivity(Notification01Activity.this, 0, notificationIntent, 0); 
 
                notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); 
 
                mNotificationManager.notify(HELLO_ID, notification); 
            } 
        }); 
         
    } 

public class Notification01Activity extends Activity {
 private Button sendBtn;
 private static final int HELLO_ID = 1;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        sendBtn = (Button)findViewById(R.id.sendBtn);
       
  String ns = Context.NOTIFICATION_SERVICE;
        final NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
        int icon = R.drawable.notification_icon;
        CharSequence tickerText = "Notification01";
        long when = System.currentTimeMillis();

        final Notification notification = new Notification(icon, tickerText, when);
       
        final Context context = getApplicationContext();
        final CharSequence contentTitle = "My notification";
        final CharSequence contentText = "Notification01!";
       
        sendBtn.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub

          Intent notificationIntent = new Intent(Notification01Activity.this, Notification01Activity.class);
          PendingIntent contentIntent = PendingIntent.getActivity(Notification01Activity.this, 0, notificationIntent, 0);

          notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

          mNotificationManager.notify(HELLO_ID, notification);
   }
  });
       
    }
} www.aiwalls.com

大傢看這些代碼,和之前給的示例代碼片段是十分類似的,這還是比較簡單的。
    第四步:運行程序可以看到這個效果:

          首先再status bar上看到我們的notification,如下圖:

 

然後打開notifications window,可以看到我們的notification,如下圖:

Managing your Notification
NotificationManager是一個用來管理所有notifications的系統服務。你必須通過getSystemService()方法來獲得對它的一個引用。例如:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
   當你想發出你的status bar notification的時候,就將Notificatiion傳遞給NotificationManager的notify(int, Notification)。第一個參數是這個notification的唯一的ID,第二個參數是一個Notification的對象。第一個參數(ID)在你的應用中必須是惟一的。對於你更新自己的notification或者是要對不同的notification采取不同的動作,這個時候這個ID號就是必須的,他就是用來識別特定的那個要更新的或者是要采取特定動作的那個notification。
   當用戶在notification window中選中瞭一個notification後,我們就希望這個notification得到用戶相應瞭,就應該被清除瞭,這個怎麼達到呢?我們可以通過在Notification的flag域中設置“FLAG_AUTO_CANCEL”標志即可。例如:
   Notification n;
   n.flag |= FLAG_AUTO_CANCEL;
   這樣就可以達到效果瞭,如果你不進行清除,那麼這個status bar notification就會一直顯示在status bar上面。當然,你也可以通過cancel(int)方法來清除特定的notification,這個方法參數就是之前的特定的那個ID,或者是使用cancelAll()方法清除你應用程序中的所有的nitifications.
創建自定義的Notification佈局
   默認的情況下,出現在notifications window中的notification包含一個標題和一條信息,就像上面示例的截圖那樣。顯示的標題和信息的內容都是通過setLatesEventInfo()方法中的contentTitle和contentText參數來指定的。然而,你也可以利用RemoteViews來實現自定義的notification的佈局。
   要為notification定義自己的佈局,就需要實例化一個TemoteViews對象來解析自定義的佈局文件,然後將RemoteViews傳遞到你自己的Notification的contentView參數域。
   下面用實例來說明:
   1.為notification創建自定義的XML文件,例如下面的custom_notification.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp" >
    <ImageView android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="10dp" />
    <TextView android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image"
        style="@style/NotificationTitle" />
    <TextView android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/image"
        android:layout_below="@id/title"
        style="@style/NotificationText" />
</RelativeLayout>
   註意:以上的兩個TextView元素都是包含再style屬性中的。在你自己的notifications中為text使用style資源是非常重要的,因為notification的背景色會因為不同的設備和不同的系統版本而變化。從Android2.3(API Level9)開始,系統給默認的notification佈局的text定義瞭style,因此,當你使用2.3或更高版本時,你應該使用這個style來確保你的text再系統背景下是可見的。
   例如:當使用低於2.3版本系統時,要使用標準的text colors,就必須使用如下的styles,此示例為:/res/values/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationText">
      <item name="android:textColor">?android:attr/textColorPrimary</item>
    </style>
    <style name="NotificationTitle">
      <item name="android:textColor">?android:attr/textColorPrimary</item>
      <item name="android:textStyle">bold</item>
    </style>
    <!– If you want a slightly different color for some text,
         consider using ?android:attr/textColorSecondary –>
</resources>
當要使用2.3或更高本版的默認的notification colors時,我們必須使用如下的styles,此示例為:res/values-v9/styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
    <style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />
</resources>
當你運行再2.3或者更高版本系統上時,你的notification中的text將會使用一樣的系統的默認定義的。這是十分重要的,因為Android的後續版本將notification的背景顏色改變為dark。繼承系統默認的定義將確保你的text在這種情況下會顯示正常,並且如果背景顏色被蓋為其他的顏色,你的text也可以適應這種變化而正常顯示。
    2.在代碼中,用RemoveViews方法來定義notification顯示的圖像和消息。然後將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.title, "Custom notification");
contentView.setTextViewText(R.id.text, "This is a custom layout");
notification.contentView = contentView;
正如這裡所看到的一樣,把應用程序的包名以及佈局文件的ID傳遞給RemoteViews構造器。然後用setImageResource()方法和setTextViewText()方法為InageView和TextView組件定義顯示內容。最後將RemoteViews對象傳遞給Notification的contentView即可。
    3.由於在使用自定義的view時不必使用setLastEventInfo()方法,所以你必須為Notification的contentIntent域定義一個Intent,如下所示:
Intent notificationIntent = new Intent(this, MyClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.contentIntent = contentIntent;
    4.可以通過如下方法發送notification:
mNotificationManager.notify(CUSTOM_VIEW_ID, notification);
RemoteViews類同樣包含一些方法使得你可以很容易的為notification的佈局中添加Chronome和ProgressBar組件。詳細的關於為notification創建自定義的佈局,可以查看RemoteViews類。
    註意:當為notification創建自定義的佈局時,你必須確保它能夠再不同的設備方向以及分辨率下都正常工作。這對於所有的佈局工作都是十分重要的,所以,不要定義過於復雜的佈局,而且要在多種情況下進行測試。

摘自 chenlong12580的專欄

發佈留言