通知欄簡介
狀態通知欄主要涉及到2個類: Notification 和 NotificationManager
Notification為通知信息類,它里面對應了通知欄的各個屬性
NotificationManager : 是狀態欄通知的管理類,負責發通知、清除通知等操作。
注冊系統Service
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
1. flags
實例化通知欄之后通過給他添加.flags屬性賦值,例如
notification.flags = Notification.FLAG_AUTO_CANCEL;
提醒標志符成員:
// 三色燈提醒,在使用三色燈提醒時候必須加該標志符
Notification.FLAG_SHOW_LIGHTS
// 發起正在運行事件(活動中),無法手動移除
Notification.FLAG_ONGOING_EVENT
// 讓聲音、振動無限循環,直到用戶響應(取消或者打開)
Notification.FLAG_INSISTENT
// 發起Notification后,鈴聲和震動均只執行一次
Notification.FLAG_ONLY_ALERT_ONCE
// 用戶單擊通知后自動消失
Notification.FLAG_AUTO_CANCEL
// 可讓通知欄點清除鍵不消失
Notification.FLAG_NO_CLEAR
// 表示正在運行的服務
Notification.FLAG_FOREGROUND_SERVICE
2. PendingIntent
使用通知欄我們可能要監聽用戶點擊通知欄和移除通知欄的事件,比如暫停/繼續下載和用戶手動移除通知欄暫停下載。
Notification mNotification = new Notification(icon, tickerText, when);
// 移除通知欄事件設置
mNotification.deleteIntent = getDeleteIntent();
// 點擊通知欄事件設置
mNotification.contentIntent = getDefalutIntent();
分別對deleteIntent和contentIntent賦值,根據action或者requestCode在接收到關播的時候進行區分,例如:
private PendingIntent getDeleteIntent() {
Intent deleteIntent = new Intent(ACTION_DELETE);
return PendingIntent.getBroadcast(mContext, DEL_REQUESTCODE, deleteIntent, PendingIntent.FLAG_CANCEL_CURRENT);
}
getBroadcast方法的官方解釋:
Retrieve a PendingIntent that will perform a broadcast..
- 在指定intent.setClass(context, XXXReceiver.class);的廣播類的時候會出現接受不到關播的情況,所以我把這段操作給取消了,發起通知欄的activity注冊廣播后即可接收。
PendingIntent的位標識符:
FLAG_ONE_SHOT 表示返回的PendingIntent僅能執行一次,執行完后自動取消
FLAG_NO_CREATE 表示如果描述的PendingIntent不存在,并不創建相應的PendingIntent,而是返回NULL
FLAG_CANCEL_CURRENT 表示相應的PendingIntent已經存在,則取消前者,然后創建新的PendingIntent,這個有利于數據保持為最新的,可以用于即時通信的通信場景
FLAG_UPDATE_CURRENT 表示更新的PendingIntent,所有對應的Intent里面的extra被更新為最新的
- 通過extra數據來區分intent,應采用PendingIntent.FLAG_UPDATE_CURRENT),且每次num不一樣
PendingIntent點擊事件設置
contentIntent:在通知窗口區域,Notification被單擊時的響應事件由該intent觸發;
deleteIntent:當用戶點擊全部清除按鈕時,響應該清除事件的Intent;
fullScreenIntent:響應緊急狀態的全屏事件(例如來電事件)
有時我們使用contentIntent實現點擊操作時發現它會自動收起手機下拉菜單,但我們并不想這樣的時候,需要自定義監聽事件,但是要注意,2.3及2.3以下版本中,自定義的通知欄中如果帶有按鈕,可能按鈕點擊事件會失靈。
// 判斷版本之后才進行監聽
if (getSystemVersion() > 10) {
Intent buttonIntent = new Intent(ACTION_BUTTON);
buttonIntent.putExtra(INTENT_BUTTONID_TAG, BUTTON_PALY_ID);
PendingIntent intent_paly = PendingIntent.getBroadcast(mContext, 2,buttonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// 更改此處的id進行某個控件的監聽
contentview.setOnClickPendingIntent(R.id.llPro, intent_paly);
}
3. RemoteViews
當我們要在通知欄實現顯示下載進度條進度時,會用到setProgress,此方法在4.0及以后版本才有用,如果為早期版本:需要自定義通知布局RemoteViews,其中包含ProgressBar視圖。
但是使用RemoteViews是有限制的:
error:android.app.RemoteServiceException: Bad notification posted from package com.example.notifications: Couldn't expand RemoteViews for: StatusBarNotification(package=com.example.notifications id=101 tag=null notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x2))
Notification的自定義布局是RemoteViews,和其他RemoteViews一樣,在自定義視圖布局文件中,僅支持FrameLayout、LinearLayout、RelativeLayout三種布局控件和AnalogClock、Chronometer、Button、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView和AdapterViewFlipper這些顯示控件,不支持這些類的子類或Android提供的其他控件。否則會引起ClassNotFoundException異常
- 遵循了以上的條件有時仍然會報錯,API 11+才能使用的style要謹慎使用,否則會報RemoteServiceException,且很難排查出來。
4. 低版本中,自定義布局中的字體顏色的設置
- 由于2.3及之前版本,背景色是白色的,而2.3以上的版本背景色是暗色的,所以在2.3之后的版本中(即API >=9的版本中),在資源文件下的src/values-v9目錄中的style.xml文件中設置它標題和內容的顏色應該為白色或其他暖色調,否則將無法看清通知欄上的內容。
5. 自定義布局的設置方法
2.3之后:
通過Builder以下方法賦于自定義布局。
mBuilder.setContent(view_custom)
2.3及2.3之前:
通過 Notification notify = mBuilder.build();
notify.contentView = view_custom;
mNotificationManager.notify(notifyId, notify)
所以有兼容2.3版本需求的項目可以直接選擇用后者。
我的博客(第一時間更新):
http://huangss.farbox.com/