天天看點

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

分類: Android 彈無虛發 2014-02-25 18:54  2575人閱讀  評論(7)  收藏  舉報 Notification 通知欄 TaskStackBuilder android style

Android的Notification是android系統中很重要的一個機制,産品人員常常利用通知欄的方式,跟使用者進行弱溝通。擁有推送通知的app要比沒有此類功能的app活躍率要高很多。另外類似于墨迹天氣,清理大師等app,也會将通知欄常駐,利用自定義的布局,友善使用者及時快捷的檢視所需的資訊和使用快捷的功能。是以Notification的使用,也在開發當中,使用的越來越頻繁。今天我就來跟大家分享一下Notification的常用事項。

我不了解大家平時怎麼使用Notification,我常常看到有些人的代碼是這樣寫的:

  1. Notification notification=new Notification(notificationIcon, notificationTitle, when);    
  2.         notification.defaults=Notification.DEFAULT_ALL;    
  3.         Intent intent=new Intent(MainActivity.this,SecondActivity.class);    
  4.         PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this, 0, intent, 0);    
  5.         notification.setLatestEventInfo(this,"測試展開title", "測試展開内容",pendingIntent);   
  6. 。。。。。。。。。。。。。  

具體的代碼我就不貼全了,因為大家如果注意IDE的提示的話,就會發現,其實這是一種不推薦的用法,API的支援已經過時了。最新的Notification的用法,是推薦使用V4包下的NotificationCompat.Builder,利用它,進行各種設定,具體的用法先别着急,我們慢慢道來。

  1. NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(  
  2.         this);  

首先,我們需要先初始化一個notifyBuilder,然後利用它的各種set方法,進行相關設定,具體的設定,我們參考下圖:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

圖示中的序号1,叫做Content title,通過這個方法來設定:

  1. notifyBuilder.setContentTitle("This is My Notification");  

圖示中的序号3,叫做Content text,利用下面的方法來設定:

  1. notifyBuilder.setContentText("Hello World");  

圖示中的需要5,叫做Small icon,利用下面的方法來設定:

  1. notifyBuilder.setSmallIcon(R.drawable.small);  

這三個參數的設定是必須的,每次調用Notification,必須得設定這三個參數。除去這三個以外,另外的2,4,6區域,分别是Large Icon,Content Info,Time,設定方法如下所示:

  1. // 如果不設定LargeIcon,那麼系統會預設将上面的SmallIcon顯示在通知選項的最左側,右下角的小圖示将不再顯示  
  2. Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bigicon);  
  3. notifyBuilder.setLargeIcon(bitmap);  
  4. // 這裡用來顯示右下角的數字  
  5. notifyBuilder.setNumber(10);  
  6. notifyBuilder.setWhen(System.currentTimeMillis());  

以上就是關于Notification的基本設定,下面,我們繼續看看其它方面的設定,直接上代碼:

  1. // 将AutoCancel設為true後,當你點選通知欄的notification後,它會自動被取消消失  
  2.         notifyBuilder.setAutoCancel(true);  
  3.         // 将Ongoing設為true 那麼notification将不能滑動删除  
  4.         // notifyBuilder.setOngoing(true);  
  5.         // 從Android4.1開始,可以通過以下方法,設定notification的優先級,優先級越高的,通知排的越靠前,優先級低的,不會在手機最頂部的狀态欄顯示圖示  
  6.         notifyBuilder.setPriority(NotificationCompat.PRIORITY_MAX);  
  7.         // notifyBuilder.setPriority(NotificationCompat.PRIORITY_MIN);  
  8.         notifyBuilder.setTicker("Hi,Notification is here");  
  9.         // Uri uri =  
  10.         // Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat);  
  11.         // Uri uri = Uri.parse("file:///mnt/sdcard/cat.mp3");  
  12.         // notifyBuilder.setSound(uri);  
  13.         // Notification.DEFAULT_ALL:鈴聲、閃光、震動均系統預設。  
  14.         // Notification.DEFAULT_SOUND:系統預設鈴聲。  
  15.         // Notification.DEFAULT_VIBRATE:系統預設震動。  
  16.         // Notification.DEFAULT_LIGHTS:系統預設閃光。  
  17.         // notifyBuilder.setDefaults(Notification.DEFAULT_ALL);  
  18.         NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  19.         mNotificationManager.notify(NOTIFY_ID, notifyBuilder.build());  

如上面的注釋所示,如果你想點選完notification後,該通知自動消失,那麼你就需要調用setAutoCancel(boolean b)這個方法,并且将其設為true,如果你想讓你的通知欄常駐,使用者無法滑動删除,也不能通過手機的清除鍵 删除,類似于墨迹天氣等app的通知欄,那麼你可以設定setOngoing方法,也設為true,這樣,通知欄隻能通過代碼調用cancel方法才能消失,很霸道地,有木有!另外,從Android4.1時代開始,系統允許設定Notification的優先級,對于優先級高的通知,會排在 通知欄的前面,并在會在手機最上端的Status Bar顯示一個圖示,如果優先級設定的較低,那麼就會被系統顯示在通知欄的後面,并且Status Bar不再顯示相應的圖示,設定優先級的方法,就是調用setPriority(int p)。另外,當啟動通知欄的時候,我們常常可以在手機最上端的Status Bar上面,會閃現一段提示語,用來提醒使用者,這段提示語具體顯示的文字,就是靠setTicker() 這個方法來實作的。除此之外,我們還可以設定,推送通知時的鈴聲、震動效果,閃光燈效果等等,具體的我就不一一列舉了,參考上面的示例代碼即可,需要注意一點的是,設定通知的鈴聲,除去調用系統自帶的外,還有兩種方式,分别是調用SD卡中的聲音檔案和項目工程自帶的聲音檔案,這兩種方式都需要用到Uri的位址,具體如何擷取這兩種的Uri,我已經在上面的代碼中,寫的很詳細了,大家可以參考上面的代碼,在自己的項目中實驗一下。

說了這麼多,還有最重要的一點沒有講,那就是在你設定完notification的各種屬性後,你需要啟動這個notification,否則就前功盡棄了,啟動的方法,如上面的示例代碼所示,你需要先擷取一個NotificationManager的執行個體,然後調用notify的方法,notifyBuilder.build()這個方法,可以執行個體化一個notification的執行個體,另外,你還需要為這個notification配置設定一個獨一無二的的id号,将來notification的更新和删除,都是依靠這個id号來做索引對應的。

有時候,我們會涉及到這麼一個需求,那就是,産品設計,希望我們能夠監聽notification的銷毀,意思就是說,當使用者手動滑動通知将其删除或者通過手機的删除按鈕将其清空時,我們希望可以捕獲到這一資訊,并作出相應的處理。比如說,我們在通知欄發送了一個通知,用來更新一個資源的下載下傳進度,當使用者删除這個通知後,我們希望可以監聽到這一變化,作出相應的處理,比如取消下載下傳,比如重新下載下傳等等,那麼,應該如何監聽取消的行為呢?請看代碼:

  1. Intent deleteIntent = new Intent(this, DeleteService.class);  
  2. int deleteCode = (int) SystemClock.uptimeMillis();  
  3. PendingIntent deletePendingIntent = PendingIntent.getService(this,  
  4.         deleteCode, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
  5. notifyBuilder.setDeleteIntent(deletePendingIntent);  

我們給notifyBuilder設定一個DeleteIntent,這裡指向了一個service,當删除的行為發生後,系統就會啟動這個service,我們就可以在這個service中,做相應的邏輯處理了,當然,這裡我隻是舉了一個例子,用來啟動service,大家也可以将Intent指向一個Activity或者一個廣播,不過PendingIntent.getService()這個方法,就需要換成PendingIntent.getActivity()或者PendingIntent.getBroadCast()這兩個方法。

上面的内容,我們大概了解了如何給notification設定顯示的内容,和如何監聽銷毀的行為。但是常常,我們會發現,除了以上功能外,我們經常遇見的情形時,當我們點選了一個notification後,就會自動打開一個頁面,展示出資訊來源的具體頁面,接下來,我們就針對這種情況,來看看代碼是如何控制的。

剛剛提到的自動跳轉頁面的功能,看似很簡單的一個邏輯,其實也包含了各種邏輯處理情況,其中最主要的是有兩種:

一:當我們處在手機桌面主屏的時候,突然來了一條郵箱的資訊,來了一封新郵件,我們點選通知欄,系統會為我們打開最新收到的郵件,當我們看完郵件後,按傳回鍵,我們并不會馬上回到手機桌面的主屏上,而是先傳回到收件箱界面,然後再傳回到郵件APP的主界面,然後再傳回到手機桌面的主屏上,它是按照郵件APP的頁面隊列傳回的。

二:還是舉剛才那個例子,當我們收到新郵件的通知後,我們點選打開新收到的郵件,當我們閱讀完之後,我們想要點選傳回鍵,立刻傳回到我們剛剛所處的界面,繼續進行剛才還在進行的任務。

這兩種情況,在産品設計中,常常出現,是以我們也要想辦法去實作,那麼如何去實作這兩種情況呢,我們一個一個來看。

首先請看第一種情況的代碼:

  1. Intent notifyIntent = new Intent(this, NotifyRegularActivity.class);  
  2. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);  
  3. stackBuilder.addParentStack(NotifyRegularActivity.class);  
  4. stackBuilder.addNextIntent(notifyIntent);  
  5. // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個參數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode  
  6. int requestCode = (int) SystemClock.uptimeMillis();  
  7. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(  
  8.         requestCode, PendingIntent.FLAG_UPDATE_CURRENT);  
  9. notifyBuilder.setContentIntent(resultPendingIntent);  

我們繼續貼上AndroidManist.xml的配置代碼:

  1. <activity  
  2.             android:name="com.example.notificationtest.MainActivity"  
  3.             android:label="@string/app_name" >  
  4.             <intent-filter>  
  5.                 <action android:name="android.intent.action.MAIN" />  
  6.                 <category android:name="android.intent.category.LAUNCHER" />  
  7.             </intent-filter>  
  8.         </activity>  
  9.         <activity  
  10.             android:name="com.example.notificationtest.OtherActivity"  
  11.             android:label="OtherActivity"  
  12.             android:parentActivityName="com.example.notificationtest.MainActivity" >  
  13.             <meta-data  
  14.                 android:name="android.support.PARENT_ACTIVITY"  
  15.                 android:value="com.example.notificationtest.MainActivity" />  
  16.         </activity>  
  17.         <activity  
  18.             android:name="com.example.notificationtest.NotifyRegularActivity"  
  19.             android:label="NotifyRegularActivity"  
  20.             android:parentActivityName="com.example.notificationtest.OtherActivity" >  
  21.             <meta-data  
  22.                 android:name="android.support.PARENT_ACTIVITY"  
  23.                 android:value="com.example.notificationtest.OtherActivity" />  
  24.         </activity>  

好,我們來分析一下上面的代碼。首先我們設定了一個Intent,将其指向 NotifyRegularActivity,然後我們用到了TaskStackBuilder,它可以用來控制界面傳回的導航堆棧。

  1. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);  
  2. stackBuilder.addParentStack(NotifyRegularActivity.class);  
  3. stackBuilder.addNextIntent(notifyIntent);  

我們利用這段代碼,首先執行個體化了一個TaskStackBuilder,然後調用addParentStack()和addNextIntent(),設定它的傳回堆棧和跳轉頁面,跳轉頁面的Intent很好了解,跟大家平時的設定方式是一樣的,那麼它的傳回堆棧是如何控制的呢?這就需要上面xml配置檔案的配置了,大家請看,在上面的配置檔案中,一共有三個Activity,分别是MainActivity,OtherActivity,和NotifyRegularActivity,其中NotifyRegularActivity就是我們點選通知欄後,要自動跳轉的界面。在配置檔案當中,

我們給後面兩個Activity,設定了這麼一個屬性android:parentActivityName,它指的就是該activity的傳回路徑,因為剛剛我們在調用addParentStack()這個方法的時候,設定的參數是NotifyRegularActivity.class是以根據上面配置檔案的配置内容,那麼它的傳回堆棧的順序就是:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

需要注意的是,為了向下相容版本,我們在設定android:parentActivityName這個屬性的時候,還需要在配置檔案中,為每個Activity進行如下設定:

  1. <meta-data  
  2.     android:name="android.support.PARENT_ACTIVITY"  
  3.     android:value="com.example.notificationtest.MainActivity" />  

具體的value的指向,就需要你自己設定了,總之,它指向了該activity的傳回頁面。對TaskStackBuilder設定完成之後,我們再通過下面的代碼擷取PendingIntent,,然後指派給notifyBuilder即可:

  1. // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個參數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode  
  2. int requestCode = (int) SystemClock.uptimeMillis();  
  3. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(  
  4.         requestCode, PendingIntent.FLAG_UPDATE_CURRENT);  
  5. notifyBuilder.setContentIntent(resultPendingIntent);  

這裡有兩點需要注意一下:

1:PendingIntent.FLAG_UPDATE_CURRENT這個參數一般有四種選擇分别是:

FLAG_CANCEL_CURRENT:如果建構的PendingIntent已經存在,則取消前一個,重新建構一個。

FLAG_NO_CREATE:如果前一個PendingIntent已經不存在了,将不再建構它。

FLAG_ONE_SHOT:表明這裡建構的PendingIntent隻能使用一次。

FLAG_UPDATE_CURRENT:如果建構的PendingIntent已經存在,那麼系統将不會重複建立,隻是把之前不同的傳值替換掉。

如果沒有特殊要求的話,我們常常會使用FLAG_UPDATE_CURRENT這個參數來構造PendingIntent,但是這樣常常會引發第二個問題,什麼問題呢?呵呵~

2:如上所述我們使用FLAG_UPDATE_CURRENT這個參數後,常常會發現,我們點選通知欄後,系統沒有響應,時靈時不靈的,很是憂郁,這是為什麼呢?原來使用FLAG_UPDATE_CURRENT這個參數後,系統不會重新建立新的PendingIntent,這樣一來,如果你傳遞的Intent的 extra參數沒有變化的話,那麼系統就會認為你沒有發送新的PendingIntent,這樣就不會重新響應你的點選事件。一般情況下,為了能夠區分每次的PendingIntent不一樣,我們常常會在構造Intent的時候,設定不同的Action或者Extra值,這樣一來,及時是使用FLAG_UPDATE_CURRENT這個參數,系統也會因為傳值參數的變化而去響應每次的點選跳轉事件。不過這種解決方法還是有些麻煩,有時候,我們根本不需要傳遞額外的Aciton或者參數值,這該怎麼辦呢?哈哈,解決代碼已經在上面的代碼中寫出來了,在stackBuilder.getPendingIntent(requestCode, PendingIntent.FLAG_UPDATE_CURRENT)這個方法中,我們注意到第一個參數,這裡,我們隻要為這個參數設定一個獨一無二的辨別,那麼剛剛提到的點選無響應的問題就迎刃而解了,我平時的設定辦法就是利用這段代碼:

  1. int requestCode = (int) SystemClock.uptimeMillis();  

擷取釋出通知時的時間,将它作為requestCode,這樣就可以避免這些問題了。不過如果你要是使用FLAG_CANCEL_CURRENT這個參數的話,就會每次都建立一個新的,那麼剛剛提到的這兩個問題,也都不存在了,具體怎麼用,看你實際的業務要求了。

上面的講解,我們就可以解決剛剛讨論的第一種情形了,下面我們來說一下,第二種情形,也就是點選傳回鍵後,直接傳回剛剛任務所處的界面,看看這個如何實作。來,看代碼:

  1. Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);  
  2.         notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  3.                 | Intent.FLAG_ACTIVITY_CLEAR_TASK);  
  4.         // Creates the PendingIntent  
  5.         // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個參數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode  
  6.         int requestCode = (int) SystemClock.uptimeMillis();  
  7.         PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,  
  8.                 notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
  9.         notifyBuilder.setContentIntent(pendIntent);  

繼續看配置檔案的設定:

  1. <activity  
  2.     android:name="com.example.notificationtest.NotifySpecialActivity"  
  3.     android:excludeFromRecents="true"  
  4.     android:label="NotifySpecialActivity"  
  5.     android:launchMode="singleTask"  
  6.     android:taskAffinity="" >  
  7. </activity>  

在代碼中,我們設定NotifySpecialActivity為我們要跳轉的界面,然後在xml的配置檔案中,我們重點設定了這三個屬性:android:excludeFromRecents="true",android:launchMode="singleTask",android:taskAffinity="",第一個屬性的設定,是将該界面從最近工作列當中移除,防止使用者通過最近工作列而進入到該界面,這樣一來,隻能通過通知來的點選來進入。第二種屬性的設定就很常見了,是為了防止該界面存在的情況下,重複建立該Activity,第三屬性是為了配置代碼中的這段來設定的:

  1. notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  2.         | Intent.FLAG_ACTIVITY_CLEAR_TASK);  

這樣的作用是為此次跳轉界面的行為重新配置設定一個任務堆棧,而不從屬于其它的任務堆棧,這樣的話,當我們點選傳回鍵後,就可以直接傳回到剛剛使用者所處的任務界面了。由于這裡我們不再使用TaskStackBuilder,是以最後需要調用PendingIntent.getActivity(this, requestCode,notifyIntent,PendingIntent.FLAG_UPDATE_CURRENT)這個方法來構造一個PendingIntent,然後指派給notifyBuilder。這樣,剛剛讨論過的第二種情形,我們就可以解決了,相比較第一種來說,這種解決方式更為簡潔,不過處理的業務邏輯也不一樣,大家斟酌而定。

Notificaton在平時的産品設計中,常常用來顯示跟網絡互動的進度,我們常常的做法是在通知欄上面,顯示一個進度條,用來更新互動的進度,這個的實作方式很簡單,主要依賴于mBuilder.setProgress()這個方法,具體的做法可以參考下面的代碼:

  1.     final NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  2.     final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(  
  3.             this);  
  4.     mBuilder.setContentTitle("Picture Download")  
  5.             .setContentText("Download in progress")  
  6.             .setSmallIcon(R.drawable.small);  
  7.     new Thread(new Runnable() {  
  8.         @Override  
  9.         public void run() {  
  10.             int incr;  
  11.             for (incr = 0; incr <= 100; incr += 5) {  
  12.                 // mBuilder.setProgress(100, incr, false);  
  13.                 mBuilder.setProgress(0, 0, true);  
  14.                 mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  
  15.                 try {  
  16.                     Thread.sleep(1 * 1000);  
  17.                 } catch (InterruptedException e) {  
  18.                 }  
  19.             }  
  20.             mBuilder.setContentText("Download complete").setProgress(0, 0,  
  21.                     false);  
  22.             mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  
  23.         }  
  24.     }  
  25.     // Starts the thread by calling the run() method in its Runnable  
  26.     ).start();  
  27. }  

在代碼中,我們開啟了一個線程,裡面進行20次for循環,每次循環都會調用setProgress這個方法,因為每次調用的NOTIFY_ID都是相同的,是以系統會根據這個ID來更新notification的進度而不會重新建立一個新的Notification。setProgress這個方法一共有兩種方法,一種是這樣的:

  1. mBuilder.setProgress(100, incr, false);  

第一個參數指的的是進度的總長度,第二個參數是目前進行的長度,然後将第三個參數設為false,我們可以看到的效果就如下圖:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

我們可以看見進度條的确切位置和進度情況。還有一種使用方法是這樣的:

  1. mBuilder.setProgress(0, 0, true);  

将前兩個參數都設為0,然後将最後這個參數設為true,這樣的進度條效果是一種連續模糊的,适合進行時間不确定的網絡連接配接,效果圖如下:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

最後,當我們的任務完成後,我們需要取消進度條的顯示,這時候我們需要調用如下方法:

  1. mBuilder.setContentText("Download complete").setProgress(0, 0,  
  2.         false);  

設定一個任務完成後的文本描述,然後将setProgress的前兩個參數都設為0,最後一個參數設為false,這樣進度條就不會在通知欄上面顯示了,效果圖:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

Notification的進度條的使用方法就是這些,如果大家平時用的不多,最好還是根據上面貼出的源代碼,自己聯系一遍,稍候我也會把本次工程的源代碼打包,上傳到CSDN的資源庫中,供大家參考。

上面跟大家介紹的,都是Notification的一種正常樣式,自從Android4.1之後,谷歌引入了一種新的樣式,叫做Big View,效果就是相對于傳統的Notification,它的顯示區域更大,顯示的内容也更多一些。關于Big View,谷歌支援了三種模式,分别是:

Big picture style 和 Big text style 還有 Inbox style

在這裡,我向大家重點介紹一下第一種樣式和第三種樣式,先給大家貼一下,這兩種的效果圖:

Big picture style

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

Inbox style

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

我們來看看代碼是如何設定Big picture style 的:

  1. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(  
  2.         this).setSmallIcon(R.drawable.small)  
  3.         .setContentTitle("Picture tracker")  
  4.         .setContentText("Picture received");  
  5. NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle();  
  6. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bigpic);  
  7. picStyle.bigPicture(bitmap);  
  8. mBuilder.setStyle(picStyle);  
  9. NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  10. mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  

首先我們執行個體化一個NotificationCompat.BigPictureStyle,然後讀取要展示的圖檔資源,調用picStyle.bigPicture(bitmap)這個方法設定圖檔,最後調用notifyBuilder的mBuilder.setStyle(picStyle)方法,設定好BIG VIEW的樣式,就OK了,代碼簡單的令人發指,我就不多解釋了,大家參考上面的示例代碼即可。

接下來,我們再看看Inbox style這種樣式是如何設定的:

  1. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(  
  2.         this).setSmallIcon(R.drawable.small)  
  3.         .setContentTitle("Inbox tracker")  
  4.         .setContentText("Inbox received");  
  5. NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();  
  6. String[] events = new String[6];  
  7. events[0] = "Hello my one world";  
  8. events[1] = "Hello my two world";  
  9. events[2] = "Hello my three world";  
  10. events[3] = "Hello my four world";  
  11. events[4] = "Hello my five world";  
  12. events[5] = "Hello my six world";  
  13. inboxStyle.setBigContentTitle("Inbox tracker details:");  
  14. for (int i = 0; i < events.length; i++) {  
  15.     inboxStyle.addLine(events[i]);  
  16. }  
  17. inboxStyle.setBigContentTitle("Thers are six messages");  
  18. inboxStyle.setSummaryText("It's so easy,right?");  
  19. mBuilder.setStyle(inboxStyle);  
  20. NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  21. mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  

唉,代碼是不是再簡單不過了,我都不好意思班門弄斧的介紹這段代碼了。主要聲明一下三個方法的使用吧,inboxStyle.addLine(),這個方法是用來設定下圖中黃色區域的文字,inboxStyle.setBigContentTitle("Thers are six messages")這個方法是用來設定紅色區域的文字内容,inboxStyle.setSummaryText("It's so easy,right?")是用來設定綠色區域的内容顯示,其他的基本設定在之前的内容中,都已經介紹了很多了,我就不重複介紹了。

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

通過上面的學習,想必大家已經對Notification有了一個比較全面的了解了,最後,我再給大家介紹一種自定義 Notification布局的用法。自定義Notification布局的app有很多,比如像墨迹天氣,Clean Master等等,利用自定義布局,将使用者所需資訊和快捷功能,多樣化的展示在通知欄上面,給大家看一下Clean Master的截圖:

Android Notificaton Android 彈無虛發之第四彈:你應該掌握的Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效)

其實要是實作這種自定義布局的Notification,非常簡單,我們這就給大家展示代碼設定和布局配置:

先看看java代碼:

  1. NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);  
  2. RemoteViews remoteView = new RemoteViews(getPackageName(),R.layout.remote);  
  3. remoteView.setTextViewText(R.id.text, "Custom Text");  
  4. remoteView.setTextViewText(R.id.btn, "Custom Button");  
  5. remoteView.setImageViewResource(R.id.image, R.drawable.ic_launcher);  
  6. Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);  
  7. notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  8.         | Intent.FLAG_ACTIVITY_CLEAR_TASK);  
  9. // Creates the PendingIntent  
  10. // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個參數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode  
  11. int requestCode = (int) SystemClock.uptimeMillis();  
  12. PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,  
  13.         notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);  
  14. remoteView.setOnClickPendingIntent(R.id.btn, pendIntent);  
  15. mBuilder.setSmallIcon(R.drawable.small);  
  16. mBuilder.setContent(remoteView);  
  17. NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  18. mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  

再來看看xml布局檔案是什麼樣的:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="64dp" >  
  5.     <ImageView  
  6.         android:id="@+id/image"  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="match_parent"  
  9.         android:layout_alignParentLeft="true"  
  10.         android:gravity="center" />  
  11.     <TextView  
  12.         android:id="@+id/text"  
  13.         android:layout_width="wrap_content"  
  14.         android:layout_height="match_parent"  
  15.         android:layout_centerInParent="true"  
  16.         android:gravity="center" />  
  17.     <Button  
  18.         android:id="@+id/btn"  
  19.         android:layout_width="wrap_content"  
  20.         android:layout_height="wrap_content"  
  21.         android:layout_alignParentRight="true"  
  22.         android:gravity="center" />  
  23. </RelativeLayout>  

我們首先利用下面這行代碼去解析上面的布局檔案

  1. RemoteViews remoteView = new RemoteViews(getPackageName(),R.layout.remote);  

然後根據每個控件的id号進行資源設定:

  1. remoteView.setTextViewText(R.id.text, "Custom Text");  
  2. remoteView.setTextViewText(R.id.btn, "Custom Button");  
  3. remoteView.setImageViewResource(R.id.image, R.drawable.ic_launcher);  

我們也可以為這些控件單獨設定點選事件,比如設定Button的點選事件:

  1. remoteView.setOnClickPendingIntent(R.id.btn, pendIntent);  

上面第二個參數pendingIntent的擷取,在之前的講解中,已經介紹了好幾種方式了,這裡我們随便選擇一種來實作了:

  1. Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);  
  2.         notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK  
  3.                 | Intent.FLAG_ACTIVITY_CLEAR_TASK);  
  4.         // Creates the PendingIntent  
  5.         // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個參數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode  
  6.         int requestCode = (int) SystemClock.uptimeMillis();  
  7.         PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,  
  8.                 notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);  

最後,我們要調用下面這段代碼,将自定義的RemoteView設定給notifyBuilder,然後調用發送通知的方法就OK了。

  1. mBuilder.setContent(remoteView);  

最後的最後,需要再給大家介紹兩個方法,那就是通過代碼來取消Notification,咱不能隻管殺不管埋啊,哈哈~

  1. NotificationManager cancelNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  2. cancelNotificationManager.cancel(NOTIFY_ID);  
  3. cancelNotificationManager.cancelAll();  

cancelNotificationManager.cancel(NOTIFY_ID)這個方法是根據之前釋出通知時,配置設定的ID号,來取消對應的通知欄。

cancelNotificationManager.cancelAll()這個方法是取消所有之前釋出過的通知欄,比較暴力一點哈。

以上就是我今天給大家分享的内容,關于Notification的内容,在上面的内容中,可能還沒有覆寫完所有的知識點,但是基本上涵蓋了我平時工作中用到的幾個關鍵用途,羅哩羅嗦的寫了一大篇,可能有些地方沒有講清楚或者我了解的有錯誤,還希望大家能夠幫我指點一二,共同進步。最後,還是老樣子,附上本次所有示例代碼的下載下傳位址,友善大家調試學習:

下載下傳位址:http://download.csdn.net/detail/pringlee2011/6960743

轉載 http://blog.csdn.net/xy_nyle/article/details/19853591