1. 程式人生 > >Notification(Notification的通知欄常駐、各種樣式、點選無效、禁止滑動刪除、相容低版本)

Notification(Notification的通知欄常駐、各種樣式、點選無效、禁止滑動刪除、相容低版本)

Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效、Notification禁止滑動刪除)

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方法,進行相關設定,具體的設定,我們參考下圖:

圖示中的序號1,叫做

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

圖示中的序號3,叫做

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

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

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

  • Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bigicon);  
  • notifyBuilder.setLargeIcon(bitmap);  
  • // 這裡用來顯示右下角的數字  
  • notifyBuilder.setNumber(10);  
  • 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(booleanb)這個方法,並且將其設為true,如果你想讓你的通知欄常駐,使用者無法滑動刪除,也不能通過手機的清除鍵刪除,類似於墨跡天氣等app的通知欄,那麼你可以設定setOngoing方法,也設為true,這樣,通知欄只能通過程式碼呼叫cancel方法才能消失,很霸道地,有木有!另外,從Android4.1時代開始,系統允許設定Notification的優先順序,對於優先順序高的通知,會排在通知欄的前面,並在會在手機最上端的Status Bar顯示一個圖示,如果優先順序設定的較低,那麼就會被系統顯示在通知欄的後面,並且Status Bar不再顯示相應的圖示,設定優先順序的方法,就是呼叫setPriority(intp)。另外,當啟動通知欄的時候,我們常常可以在手機最上端的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: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,我們可以看到的效果就如下圖:

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

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

將前兩個引數都設為0,然後將最後這個引數設為true,這樣的進度條效果是一種連續模糊的,適合進行時間不確定的網路連線,效果圖如下:

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

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

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

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

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

Big text style還有 new NotificationCompat.Builder(  

  •         this).setSmallIcon(R.drawable.small)  
  •         .setContentTitle("Picture tracker")  
  •         .setContentText("Picture received");  
  • NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle();  
  • Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bigpic);  
  • picStyle.bigPicture(bitmap);  
  • mBuilder.setStyle(picStyle);  
  • NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  • mNotifyManager.notify(NOTIFY_ID, mBuilder.build());  

首先我們例項化一個NotificationCompat.BigPictureStyle,然後讀取要展示的圖片資源,呼叫picStyle.bigPicture(bitmap)這個方法設定圖片,最後呼叫notifyBuilder的mBuilder.setStyle(picStyle)方法,設定好BIGVIEW的樣式,就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 soeasy,right?")是用來設定綠色區域的內容顯示,其他的基本設定在之前的內容中,都已經介紹了很多了,我就不重複介紹了。

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

其實要是實現這種自定義佈局的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()這個方法是取消所有之前釋出過的通知欄,比較暴力一點哈。

相關推薦

NotificationNotification通知欄常駐各種樣式無效禁止滑動刪除相容版本

Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效、Notification禁止滑動刪除) Android的Notification是android系統中很重要的一個機制, 產品人員常常利用通

如何用資料驅動實現通用化巡檢APP如何一個介面裡新增多個拍照按鈕並顯示在不同的imageview裡

最近啟動了一個新專案叫通用化,老師的設想是這樣的:APP裡顯示的內容和佈局都是不確定的,需要從後臺傳過來的json串中解析出來,然後經過一系列的迴圈和判斷語句,為APP新增上json中要求的佈局和內容,就連文字的大小和顏色也都是從後臺獲取的。 剛開始的時候覺得

iOS抽屜效果二級選單,拖拽滑動

好像最近,看到好多Android上的抽屜效果,也忍不住想要自己寫一個。在Android裡面可以用SlidingDrawer,很方便的實現。IOS上面就只有自己寫了。其實原理很簡單就是 UIView 的移動,和一些手勢的操作。 // // 

陰陽師魂十掛機實現後臺控制代碼截圖+滑鼠

        學習繁忙,但是作為癢癢鼠的忠實粉,抽空寫了個小指令碼,後臺掛機魂十,業原火,御靈,覺醒,還是美滋滋的。 指令碼實現的關鍵主要有兩部分:一是通過控制代碼後臺獲得截圖,二是通過控制代碼後臺對視窗傳送滑鼠點選

leaflet選中要素,設定向量樣式要素獲取其屬性

leaflet自身沒有選擇的控制,需要自己寫程式碼實現 主要是通過featurelayer的onclick事件來設定點選要素的style,並獲取對應feature的屬性資訊 let featureLayer = L.esri.featureLayer({ url:'http://mg

git分支管理建立分支,分支間轉換,檢視分支,合併分支,刪除分支,分支衝突

分支(branch)這玩意兒我也不知道該怎麼解釋,就按照自己的理解來吧~ 在你第一次commit的時候,git會自動建立一個master分支(當然前提是你沒有在這之前就轉換到另一個分支上),這就是主線。有的時候,會想對倉庫進行某些操作,但是我們又不想影響到倉庫當前的狀態,這個時候就可以建立一

pc端手機端瀏覽器微信內.返回鍵,返回到上一個頁面瀏覽的位置的實現

第一步:需要注意引入的js jquery.js jquery.cookie.js 第二部:在被返回的前一頁加入以下程式碼 <script type="text/javascript"> $(function () {

android狀態列一體化沉浸式狀態列(相容版本)

<TextView            android:id="@+id/tv_title"            android:layout_centerVertical="true"            android:layout_width="match_parent"          

IDEA開啟游標是粗黑色,backspace鍵insert鍵無效的解決辦法

問題描述: 開啟IDEA的編譯器之後,介面顯示的游標變粗,點選backspace鍵和insert鍵盤之後無效 解決方法: 開啟File——Settings——Plugins,在右側的搜尋欄

Android文字編輯進行縮放移動和改變字型顏色的實現

實現效果如下: 需求功能點包含: 1:介面的文字為動態新增; 2:點選介面中的文字,開啟編輯模式:可編輯文字內容,可設定字型顏色,字型型別,粗體及對齊等; 3:點選刪除從介面上清除文字塊; 4:拖動編輯模式下的文字塊的四個錨點,可以按文字中心位置縮放,同時工具欄跟隨文字

移動端pc端通用複製

點選複製 function copyArticle(event){ const range = document.createRange(); range.selectNode(document.getElementById('dd')); const selection = w

webpack 4.14.0 版本太高,無法執行相關指令,將webpack高版本切換到版本--直接覆蓋

(1)問題:webpack 4.14.0 版本太高,無法執行相關指令,(2) 解決辦法:將高版本切換到低版本(3)實現webpack 4.14.0 版本太高,無法執行相關指令,指令不熟悉,高版本切換到低版本,

SoundPool工具類單例模式相容版本

public class ClickSoundUtil { private Context context; private static SoundPool soundPool; private static int soundID; public stat

ng-repeat設定第一個元素為預設樣式其餘元素切換樣式

如何在ng-repeat時預設第一個元素background-color為紅色,點選對應元素背景變紅同時更換其他全為黑色 提供一個簡單思路: JS: $scope.isActive = 0; $scope.arr = [ { //code he

EditText控制元件的基本使用Button按鈕,Toast提示EditText中的內容

EditText是程式用於和使用者進行互動的另一個重要控制元件,它允許使用者在空間裡輸入和編輯內容,並可以在程式中對這些內容進行處理。EditText的應用場景非常普遍,在進行發簡訊、發微博、聊QQ等操作時,你不得不使用EditText。接下來我們直接看實現效果圖,再看程式碼。 效果圖:

Android跳轉到聯絡人列表撥號面板和通話記錄

public class MainActivity extends Activity {  private String mTelNum=10086;  @Override  protected void onCreate(Bundle savedInstanceState

iOS通用連結Universal Links突然無效的解決方案

問題描述 測試告訴我,如果從微信開啟App之後,點選App右上角的應用網址之後,iOS通用連結就費了,在也用不了了,如圖: 原因分析 因為你點選右上角的網址之後,預設就把通用連結禁

【IOS】實現IOS版的抽屜效果,拖拽滑動

原文連結:http://blog.csdn.net/toss156/article/details/7400065 好像最近,看到好多Android上的抽屜效果,也忍不住想要自己寫一個。在Android裡面可以用SlidingDrawer,很方便的實現。IOS上面就只有自

android之View座標系view獲取自身座標的方法和事件中座標的獲取

在做一個view背景特效的時候被座標的各個獲取方法搞暈了,幾篇抄來抄去的部落格也沒弄很清楚。 現在把整個總結一下。 其實只要把下面這張圖看明白就沒問題了。 涉及到的方法一共有下面幾個: view獲取自身座標:getLeft(),getTop(),getRigh

百度地圖MapMarker以及Label事件的區分

當我們同時為Marker和Map新增click事件後,會發現點選Marker時,不僅觸發了Marker的click事件,Map的click事件也會同時被觸發。實際上點選地圖上的任何覆蓋物都會傳遞到Map,這是因為API會將事件向上傳遞。那麼如何區分呢?在Map的