原文出處: http://www.androidchina.net/6174.html
Notification在Android中使用的頻率可以說(shuō)是非常高的,本篇博客,我將圍繞著Notification的各方面進(jìn)行解析,使大家對(duì)Notification有更好的認(rèn)識(shí)。
Notification的使用步驟
1.獲取NotificationManager
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
2.創(chuàng)建NotificationCompat.Builder
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
3.對(duì)Builder設(shè)置一些Notification相關(guān)屬性:
mBuilder.setContentTitle("標(biāo)題")//設(shè)置通知欄標(biāo)題
.setContentText("內(nèi)容") //設(shè)置通知欄顯示內(nèi)容
.setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL)) //設(shè)置通知欄點(diǎn)擊意圖
//? .setNumber(number) //設(shè)置通知集合的數(shù)量
.setTicker("通知到來(lái)") //通知首次出現(xiàn)在通知欄,帶上升動(dòng)畫(huà)效果的
.setWhen(System.currentTimeMillis())//通知產(chǎn)生的時(shí)間,會(huì)在通知信息里顯示,一般是系統(tǒng)獲取到的時(shí)間
.setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知優(yōu)先級(jí)
//? .setAutoCancel(true)//設(shè)置這個(gè)標(biāo)志當(dāng)用戶單擊面板就可以讓通知將自動(dòng)取消
.setOngoing(false)//ture,設(shè)置他為一個(gè)正在進(jìn)行的通知。他們通常是用來(lái)表示一個(gè)后臺(tái)任務(wù),用戶積極參與(如播放音樂(lè))或以某種方式正在等待,因此占用設(shè)備(如一個(gè)文件下載,同步操作,主動(dòng)網(wǎng)絡(luò)連接)
.setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加聲音、閃燈和振動(dòng)效果的最簡(jiǎn)單、最一致的方式是使用當(dāng)前的用戶默認(rèn)設(shè)置,使用defaults屬性,可以組合
//Notification.DEFAULT_ALL? Notification.DEFAULT_SOUND 添加聲音 // requires VIBRATE permission
.setSmallIcon(R.drawable.ic_launcher);//設(shè)置通知小ICON
4.使用Builder創(chuàng)建通知
Notification notification = mBuilder.build();
5.使用NotificationManager將通知推送出去
int id = 199;
LogUtils.d(TAG, "創(chuàng)建通知");
mNotificationManager.notify(id, notification);
Notification 的基本操作主要有創(chuàng)建、更新、取消這三種。一個(gè) Notification 的必要屬性有三項(xiàng),如果不設(shè)置則在運(yùn)行時(shí)會(huì)拋出異常:
小圖標(biāo),通過(guò) setSmallIcon() 方法設(shè)置
標(biāo)題,通過(guò) setContentTitle() 方法設(shè)置
內(nèi)容,通過(guò) setContentText() 方法設(shè)置
除了以上三項(xiàng),其它均為可選項(xiàng)。雖然如此,但還是應(yīng)該給 Notification 設(shè)置一個(gè) Action ,這樣就可以直接跳轉(zhuǎn)到 App 的某個(gè) Activity 、啟動(dòng)一個(gè) Service 或者發(fā)送一個(gè) Broadcast。否則,Notification 僅僅只能起到通知的效果,而不能與用戶交互。
當(dāng)系統(tǒng)接收到通知時(shí),可以通過(guò)震動(dòng)、響鈴、呼吸燈等多種方式進(jìn)行提醒。
1) setSmallIcon() 與 setLargeIcon()
在 NotificationCompat.Builder 中有設(shè)置通知的大小圖標(biāo)的兩個(gè)方法。這兩個(gè)方法有什么區(qū)別呢?當(dāng) setSmallIcon() 與 setLargeIcon() 同時(shí)存在時(shí), smallIcon 顯示在largeIcon的右下角;當(dāng)只設(shè)置 setSmallIcon() 時(shí), smallIcon 顯示在左側(cè)。看下圖你就明白了。對(duì)于部分 ROM ,可能修改過(guò)源碼,如 MIUI 上通知的大圖標(biāo)和小圖標(biāo)是沒(méi)有區(qū)別的。
Google 官方是這么解釋 setSmallIcon() 這個(gè)方法的:
Set the small icon resource, which will be used to represent the notification in the status bar. The platform template for the expanded view will draw this icon in the left, unless a large icon has also been specified, in which case the small icon will be moved to the right-hand side.
2) 設(shè)置提醒標(biāo)志符Flags
方法解釋:提醒標(biāo)志符,向通知添加聲音、閃燈和振動(dòng)效果等設(shè)置達(dá)到通知提醒效果,可以組合多個(gè)屬性
a) 創(chuàng)建通知欄之后通過(guò)給他添加.flags屬性賦值。
1.? Notification notification = mBuilder.build();
2.? notification.flags = Notification.FLAG_AUTO_CANCEL;b)? 通過(guò)setContentIntent(PendingIntent intent)方法中的意圖設(shè)置對(duì)應(yīng)的flags1.? public PendingIntent getDefalutIntent(int flags){
2.? ? ? PendingIntent pendingIntent= PendingIntent.getActivity(this, 1, new Intent(), flags);
3.? ? ? return pendingIntent;
4.? }
各標(biāo)志符介紹
Notification.FLAG_SHOW_LIGHTS? ? ? ? ? ? ? //三色燈提醒,在使用三色燈提醒時(shí)候必須加該標(biāo)志符
Notification.FLAG_ONGOING_EVENT? ? ? ? ? //發(fā)起正在運(yùn)行事件(活動(dòng)中)
Notification.FLAG_INSISTENT? //讓聲音、振動(dòng)無(wú)限循環(huán),直到用戶響應(yīng) (取消或者打開(kāi))
Notification.FLAG_ONLY_ALERT_ONCE? //發(fā)起Notification后,鈴聲和震動(dòng)均只執(zhí)行一次
Notification.FLAG_AUTO_CANCEL? ? ? //用戶單擊通知后自動(dòng)消失
Notification.FLAG_NO_CLEAR? ? ? ? ? //只有全部清除時(shí),Notification才會(huì)清除 ,不清楚該通知(QQ的通知無(wú)法清除,就是用的這個(gè))
Notification.FLAG_FOREGROUND_SERVICE? ? //表示正在運(yùn)行的服務(wù)
3) .setDefaults(int defaults) (NotificationCompat.Builder中的方法,用于設(shè)置通知到來(lái)時(shí),通過(guò)什么方式進(jìn)行提示)
方法解釋:向通知添加聲音、閃燈和振動(dòng)效果的最簡(jiǎn)單、使用默認(rèn)(defaults)屬性,可以組合多個(gè)屬性(和方法1中提示效果一樣的)
對(duì)應(yīng)屬性:
Notification.DEFAULT_VIBRATE //添加默認(rèn)震動(dòng)提醒 需要 VIBRATE permission
Notification.DEFAULT_SOUND // 添加默認(rèn)聲音提醒
Notification.DEFAULT_LIGHTS// 添加默認(rèn)三色燈提醒
Notification.DEFAULT_ALL// 添加默認(rèn)以上3種全部提醒
/**
* 顯示帶有默認(rèn)鈴聲、震動(dòng)、呼吸燈效果的通知
* 如需實(shí)現(xiàn)自定義效果,請(qǐng)參考后面三個(gè)例子
*/
private void showNotifyWithMixed() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是有鈴聲+震動(dòng)+呼吸燈效果的通知")
.setContentText("庫(kù)里就是叼~")
//等價(jià)于setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
.setDefaults(Notification.DEFAULT_ALL);
mManager.notify(5, builder.build());
}
4) setVibrate(long[] pattern)
方法解釋:設(shè)置震動(dòng)的時(shí)間
.setVibrate(new long[] {0,300,500,700});
實(shí)現(xiàn)效果:延遲0ms,然后振動(dòng)300ms,在延遲500ms,接著在振動(dòng)700ms。
還有另外一種寫(xiě)法:
mBuilder.build().vibrate = new long[] {0,300,500,700};
如果希望設(shè)置默認(rèn)振動(dòng)方式,設(shè)置了方法(2)中默認(rèn)為DEFAULT_VIBRATE 即可。
例子:
/**
* 展示有震動(dòng)效果的通知,需要在AndroidManifest.xml中申請(qǐng)震動(dòng)權(quán)限
*
* 補(bǔ)充:測(cè)試震動(dòng)的時(shí)候,手機(jī)的模式一定要調(diào)成鈴聲+震動(dòng)模式,否則你是感受不到震動(dòng)的
*/
private void showNotifyWithVibrate() {
//震動(dòng)也有兩種設(shè)置方法,與設(shè)置鈴聲一樣,在此不再贅述
long[] vibrate = new long[]{0, 500, 1000, 1500};
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是伴有震動(dòng)效果的通知")
.setContentText("顫抖吧,凡人~")
//使用系統(tǒng)默認(rèn)的震動(dòng)參數(shù),會(huì)與自定義的沖突
//.setDefaults(Notification.DEFAULT_VIBRATE)
//自定義震動(dòng)效果
.setVibrate(vibrate);
//另一種設(shè)置震動(dòng)的方法
//Notification notify = builder.build();
//調(diào)用系統(tǒng)默認(rèn)震動(dòng)
//notify.defaults = Notification.DEFAULT_VIBRATE;
//調(diào)用自己設(shè)置的震動(dòng)
//notify.vibrate = vibrate;
//mManager.notify(3,notify);
mManager.notify(3, builder.build());
}
4)方法:.setLights(intledARGB ,intledOnMS ,intledOffMS )
方法解釋:android支持三色燈提醒,這個(gè)方法就是設(shè)置不同場(chǎng)景下的不同顏色的燈。
描述:其中l(wèi)edARGB 表示燈光顏色、 ledOnMS 亮持續(xù)時(shí)間、ledOffMS 暗的時(shí)間。
注意:
1)只有在設(shè)置了標(biāo)志符Flags為Notification.FLAG_SHOW_LIGHTS的時(shí)候,才支持三色燈提醒。
2)這邊的顏色跟設(shè)備有關(guān),不是所有的顏色都可以,要看具體設(shè)備。
Notification notify = mBuilder.build();
notify .setLights(0xff00eeff, 500, 200)
同理,以下方法也可以設(shè)置同樣效果:
Notification notify = mBuilder.build();
notify.flags = Notification.FLAG_SHOW_LIGHTS;
notify.ledARGB = 0xff00eeff;
notify.ledOnMS = 500;
notify.ledOffMS = 400;
如果希望使用默認(rèn)的三色燈提醒,設(shè)置了方法(2)中默認(rèn)為DEFAULT_LIGHTS即可。
例子:
/**
* 顯示帶有呼吸燈效果的通知,但是不知道為什么,自己這里測(cè)試沒(méi)成功
*/
private void showNotifyWithLights() {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是帶有呼吸燈效果的通知")
.setContentText("一閃一閃亮晶晶~")
//ledARGB 表示燈光顏色、 ledOnMS 亮持續(xù)時(shí)間、ledOffMS 暗的時(shí)間
.setLights(0xFF0000, 3000, 3000);
Notification notify = builder.build();
//只有在設(shè)置了標(biāo)志符Flags為Notification.FLAG_SHOW_LIGHTS的時(shí)候,才支持呼吸燈提醒。
notify.flags = Notification.FLAG_SHOW_LIGHTS;
//設(shè)置lights參數(shù)的另一種方式
//notify.ledARGB = 0xFF0000;
//notify.ledOnMS = 500;
//notify.ledOffMS = 5000;
//使用handler延遲發(fā)送通知,因?yàn)檫B接usb時(shí),呼吸燈一直會(huì)亮著
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mManager.notify(4, builder.build());
}
}, 10000);
}
5)方法:.setSound(Uri sound)
方法解釋:設(shè)置默認(rèn)或則自定義的鈴聲,來(lái)提醒。
//獲取默認(rèn)鈴聲
.setDefaults(Notification.DEFAULT_SOUND)
//獲取自定義鈴聲
.setSound(Uri.parse("file:///sdcard/dance.mp3"))
//獲取Android多媒體庫(kù)內(nèi)的鈴聲
.setSound(Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "5"))
同理相同效果的另一種設(shè)置方法這邊就不講, 和上面的都是一樣的。
例子:
/**
* 展示有自定義鈴聲效果的通知
* 補(bǔ)充:使用系統(tǒng)自帶的鈴聲效果:Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
*/
private void showNotifyWithRing() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是伴有鈴聲效果的通知")
.setContentText("美妙么?安靜聽(tīng)~")
//調(diào)用系統(tǒng)默認(rèn)響鈴,設(shè)置此屬性后setSound()會(huì)無(wú)效
//.setDefaults(Notification.DEFAULT_SOUND)
//調(diào)用系統(tǒng)多媒體褲內(nèi)的鈴聲
//.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
//調(diào)用自己提供的鈴聲,位于 /res/values/raw 目錄下
.setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound));
//另一種設(shè)置鈴聲的方法
//Notification notify = builder.build();
//調(diào)用系統(tǒng)默認(rèn)鈴聲
//notify.defaults = Notification.DEFAULT_SOUND;
//調(diào)用自己提供的鈴聲
//notify.sound = Uri.parse("android.resource://com.littlejie.notification/"+R.raw.sound);
//調(diào)用系統(tǒng)自帶的鈴聲
//notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
//mManager.notify(2,notify);
mManager.notify(2, builder.build());
}
6)方法:.setPriority(int pri)
方法解釋:設(shè)置優(yōu)先級(jí)(實(shí)際項(xiàng)目中并無(wú)大用,設(shè)置最高級(jí)也不會(huì)使得你的通知欄出現(xiàn)在第一位)
對(duì)應(yīng)屬性:
Notification.PRIORITY_DEFAULT(優(yōu)先級(jí)為0)
Notification.PRIORITY_HIGH
Notification.PRIORITY_LOW
Notification.PRIORITY_MAX(優(yōu)先級(jí)為2)
Notification.PRIORITY_MIN(優(yōu)先級(jí)為-2)
Notification.PRIORITY_MAX是優(yōu)先級(jí)最高,Notification.PRIORITY_MIN優(yōu)先級(jí)最低
7)方法:setOngoing(boolean ongoing)
方法解釋:設(shè)置為ture,表示它為一個(gè)正在進(jìn)行的通知。他們通常是用來(lái)表示一個(gè)后臺(tái)任務(wù),用戶積極參與(如播放音樂(lè))或以某種方式正在等待,因此占用設(shè)備(如一個(gè)文件下載,同步操作,主動(dòng)網(wǎng)絡(luò)連接)
PS:我們看到360手機(jī)衛(wèi)士的通知欄一直固定在手機(jī)中,就是通過(guò)設(shè)置這個(gè)標(biāo)記,使用該標(biāo)記后你的通知欄無(wú)法被用戶手動(dòng)進(jìn)行刪除,只能通過(guò)代碼進(jìn)行刪除,慎用
8)setProgress(int max, int progress,boolean indeterminate)
屬性:max:進(jìn)度條最大數(shù)值 、progress:當(dāng)前進(jìn)度、indeterminate:表示進(jìn)度是否不確定,true為不確定,false為確定
功能:設(shè)置帶進(jìn)度條的通知,可以在下載中使用
注意:此方法在4.0及以后版本才有用,如果為早期版本:需要自定義通知布局,其中包含ProgressBar視圖
使用:如果為確定的進(jìn)度條:調(diào)用setProgress(max, progress, false)來(lái)設(shè)置通知,在更新進(jìn)度的時(shí)候在此發(fā)起通知更新progress,并且在下載完成后要移除進(jìn)度條,通過(guò)調(diào)用setProgress(0, 0, false)既可。
如果為不確定(持續(xù)活動(dòng))的進(jìn)度條,這是在處理進(jìn)度無(wú)法準(zhǔn)確獲知時(shí)顯示活動(dòng)正在持續(xù),所以調(diào)用setProgress(0, 0, true) ,操作結(jié)束時(shí),調(diào)用setProgress(0, 0, false)并更新通知以移除指示條
9)如何更新 Notification
更新通知很簡(jiǎn)單,只需要再次發(fā)送相同 ID 的通知即可,如果之前的通知還未被取消,則會(huì)直接更新該通知相關(guān)的屬性;如果之前的通知已經(jīng)被取消,則會(huì)重新創(chuàng)建一個(gè)新通知。
更新通知跟發(fā)送通知使用相同的方式。
private void refreshNotification() {
//獲取NotificationManager實(shí)例
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//實(shí)例化NotificationCompat.Builde并設(shè)置相關(guān)屬性
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//設(shè)置小圖標(biāo)
.setSmallIcon(R.mipmap.icon_fab_repair)
//設(shè)置通知標(biāo)題
.setContentTitle("最簡(jiǎn)單的Notification")
//設(shè)置通知內(nèi)容
.setContentText("只有小圖標(biāo)、標(biāo)題、內(nèi)容")
//設(shè)置通知時(shí)間,默認(rèn)為系統(tǒng)發(fā)出通知的時(shí)間,通常不用設(shè)置
//.setWhen(System.currentTimeMillis());
//通過(guò)builder.build()方法生成Notification對(duì)象,并發(fā)送通知,id=1
notifyManager.notify(1, builder.build());
}
10)如何取消 Notification?
取消通知有如下 5 種方式:
1. 點(diǎn)擊通知欄的清除按鈕,會(huì)清除所有可清除的通知
2. 設(shè)置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,點(diǎn)擊該通知時(shí)會(huì)清除它
3. 通過(guò) NotificationManager 調(diào)用 cancel(int id) 方法清除指定 ID 的通知
4. 通過(guò) NotificationManager 調(diào)用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
5. 通過(guò) NotificationManager 調(diào)用 cancelAll() 方法清除所有該應(yīng)用之前發(fā)送的通知
如果你是通過(guò) NotificationManager.notify(String tag, int id, Notification notify) 方法創(chuàng)建的通知,那么只能通過(guò) NotificationManager.cancel(String tag, int id) 方法才能清除對(duì)應(yīng)的通知,調(diào)用NotificationManager.cancel(int id) 無(wú)效。
例子:
public class DemoActivity extends Activity implements View.OnClickListener {
//Notification.FLAG_FOREGROUND_SERVICE? ? //表示正在運(yùn)行的服務(wù)
public static final String NOTIFICATION_TAG = "test";
public static final int DEFAULT_NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_simple_notification);
findViewById(R.id.btn_remove_all_notification).setOnClickListener(this);
findViewById(R.id.btn_send_notification).setOnClickListener(this);
findViewById(R.id.btn_remove_notification).setOnClickListener(this);
findViewById(R.id.btn_send_notification_with_tag).setOnClickListener(this);
findViewById(R.id.btn_remove_notification_with_tag).setOnClickListener(this);
findViewById(R.id.btn_send_ten_notification).setOnClickListener(this);
findViewById(R.id.btn_send_flag_no_clear_notification).setOnClickListener(this);
findViewById(R.id.btn_send_flag_ongoing_event_notification).setOnClickListener(this);
findViewById(R.id.btn_send_flag_auto_cancecl_notification).setOnClickListener(this);
mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_remove_all_notification:
//移除當(dāng)前 Context 下所有 Notification,包括 FLAG_NO_CLEAR 和 FLAG_ONGOING_EVENT
mNotificationManager.cancelAll();
break;
case R.id.btn_send_notification:
//發(fā)送一個(gè) Notification,此處 ID = 1
sendNotification();
break;
case R.id.btn_remove_notification:
//移除 ID = 1 的 Notification,注意:該方法只針對(duì)當(dāng)前 Context。
mNotificationManager.cancel(DEFAULT_NOTIFICATION_ID);
break;
case R.id.btn_send_notification_with_tag:
//發(fā)送一個(gè) ID = 1 并且 TAG = littlejie 的 Notification
//注意:此處發(fā)送的通知與 sendNotification() 發(fā)送的通知并不沖突
//因?yàn)榇颂幍?Notification 帶有 TAG
sendNotificationWithTag();
break;
case R.id.btn_remove_notification_with_tag:
//移除一個(gè) ID = 1 并且 TAG = littlejie 的 Notification
//注意:此處移除的通知與 NotificationManager.cancel(int id) 移除通知并不沖突
//因?yàn)榇颂幍?Notification 帶有 TAG
mNotificationManager.cancel(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID);
break;
case R.id.btn_send_ten_notification:
//連續(xù)發(fā)十條 Notification
sendTenNotifications();
break;
case R.id.btn_send_flag_no_clear_notification:
//發(fā)送 ID = 1, flag = FLAG_NO_CLEAR 的 Notification
//下面兩個(gè) Notification 的 ID 都為 1,會(huì)發(fā)現(xiàn) ID 相等的 Notification 會(huì)被最新的替換掉
sendFlagNoClearNotification();
break;
case R.id.btn_send_flag_auto_cancecl_notification:
sendFlagOngoingEventNotification();
break;
case R.id.btn_send_flag_ongoing_event_notification:
sendFlagAutoCancelNotification();
break;
}
}
/**
* 發(fā)送最簡(jiǎn)單的通知,該通知的ID = 1
*/
private void sendNotification() {
//這里使用 NotificationCompat 而不是 Notification ,因?yàn)?Notification 需要 API 16 才能使用
//NotificationCompat 存在于 V4 Support Library
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification")
.setContentText("Hi,My id is 1");
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, builder.build());
}
/**
* 使用notify(String tag, int id, Notification notification)方法發(fā)送通知
* 移除對(duì)應(yīng)通知需使用 cancel(String tag, int id)
*/
private void sendNotificationWithTag() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification With Tag")
.setContentText("Hi,My id is 1,tag is " + NOTIFICATION_TAG);
mNotificationManager.notify(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID, builder.build());
}
/**
* 循環(huán)發(fā)送十個(gè)通知
*/
private void sendTenNotifications() {
for (int i = 0; i < 10; i++) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification Batch")
.setContentText("Hi,My id is " + i);
mNotificationManager.notify(i, builder.build());
}
}
/**
* 設(shè)置FLAG_NO_CLEAR
* 該 flag 表示該通知不能被狀態(tài)欄的清除按鈕給清除掉,也不能被手動(dòng)清除,但能通過(guò) cancel() 方法清除
* Notification.flags屬性可以通過(guò) |= 運(yùn)算疊加效果
*/
private void sendFlagNoClearNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification Use FLAG_NO_CLEAR")
.setContentText("Hi,My id is 1,i can't be clear.");
Notification notification = builder.build();
//設(shè)置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_NO_CLEAR 表示該通知不能被狀態(tài)欄的清除按鈕給清除掉,也不能被手動(dòng)清除,但能通過(guò) cancel() 方法清除
//flags 可以通過(guò) |= 運(yùn)算疊加效果
notification.flags |= Notification.FLAG_NO_CLEAR;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
/**
* 設(shè)置FLAG_AUTO_CANCEL
* 該 flag 表示用戶單擊通知后自動(dòng)消失
*/
private void sendFlagAutoCancelNotification() {
//設(shè)置一個(gè)Intent,不然點(diǎn)擊通知不會(huì)自動(dòng)消失
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(
this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification Use FLAG_AUTO_CLEAR")
.setContentText("Hi,My id is 1,i can be clear.")
.setContentIntent(resultPendingIntent);
Notification notification = builder.build();
//設(shè)置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_AUTO_CANCEL 表示該通知能被狀態(tài)欄的清除按鈕給清除掉
//等價(jià)于 builder.setAutoCancel(true);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
/**
* 設(shè)置FLAG_ONGOING_EVENT
* 該 flag 表示發(fā)起正在運(yùn)行事件(活動(dòng)中)
*/
private void sendFlagOngoingEventNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Send Notification Use FLAG_ONGOING_EVENT")
.setContentText("Hi,My id is 1,i can't be clear.");
Notification notification = builder.build();
//設(shè)置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_ONGOING_EVENT 表示該通知通知放置在正在運(yùn)行,不能被手動(dòng)清除,但能通過(guò) cancel() 方法清除
//等價(jià)于 builder.setOngoing(true);
notification.flags |= Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
}
給Notification設(shè)置PendingIntent
PendingIntent可以通過(guò)setContentIntent(PendingIntent intent)這個(gè)方法進(jìn)行設(shè)置
當(dāng)我們點(diǎn)擊通知欄時(shí)想跳轉(zhuǎn)一個(gè)Activity或者開(kāi)啟一個(gè)service時(shí),就可以通過(guò)設(shè)置PendingIntent達(dá)成
PendingIntent 是 Android 系統(tǒng)管理并持有的用于描述和獲取原始數(shù)據(jù)的對(duì)象的標(biāo)志(引用)。也就是說(shuō),即便創(chuàng)建該P(yáng)endingIntent對(duì)象的進(jìn)程被殺死了,這個(gè)PendingItent對(duì)象在其他進(jìn)程中還是可用的。
日常使用中的短信、鬧鐘等都用到了 PendingIntent。
PendingIntent 主要可以通過(guò)以下三種方式獲取:
//獲取一個(gè)用于啟動(dòng) Activity 的 PendingIntent 對(duì)象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);
//獲取一個(gè)用于啟動(dòng) Service 的 PendingIntent 對(duì)象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);
//獲取一個(gè)用于向 BroadcastReceiver 廣播的 PendingIntent 對(duì)象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
PendingIntent 具有以下幾種 flag:
FLAG_CANCEL_CURRENT:如果當(dāng)前系統(tǒng)中已經(jīng)存在一個(gè)相同的 PendingIntent 對(duì)象,那么就將先將已有的 PendingIntent 取消,然后重新生成一個(gè) PendingIntent 對(duì)象。
FLAG_NO_CREATE:如果當(dāng)前系統(tǒng)中不存在相同的 PendingIntent 對(duì)象,系統(tǒng)將不會(huì)創(chuàng)建該 PendingIntent 對(duì)象而是直接返回 null 。
FLAG_ONE_SHOT:該 PendingIntent 只作用一次。
FLAG_UPDATE_CURRENT:如果系統(tǒng)中已存在該 PendingIntent 對(duì)象,那么系統(tǒng)將保留該 PendingIntent 對(duì)象,但是會(huì)使用新的 Intent 來(lái)更新之前 PendingIntent 中的 Intent 對(duì)象數(shù)據(jù),例如更新 Intent 中的 Extras 。
自定義Notification
Android系統(tǒng)允許使用RemoteViews來(lái)自定義通知。自定義普通視圖通知高度限制為64dp,大視圖通知高度限制為256dp。同時(shí),建議自定義通知盡量簡(jiǎn)單,以提高兼容性。
自定義通知需要做如下操作:1、創(chuàng)建自定義通知布局2、使用RemoteViews定義通知組件,如圖標(biāo)、文字等3、調(diào)用setContent()將RemoteViews對(duì)象綁定到NotificationCompat.Builder4、同正常發(fā)送通知流程
注意: 避免為通知設(shè)置背景,因?yàn)榧嫒菪栽?,有些文字可能看不清?/p>
關(guān)于自定義Notification兼容問(wèn)題,請(qǐng)閱讀我的另一篇博客Android通知欄版本兼容解決方案
例子:
RemoteViews notifactionView = new RemoteViews(mContext.getPackageName(),
R.layout.cl_screen_notification);
mBuilder.setContent(notifactionView);
notifactionView.setOnClickPendingIntent(R.id.cl_screen_notification, pendingIntent);
Bitmap pluginIcon = drawableToBitmap(pluginDrawable);
LogUtils.d("myl", "獲得icon" + pluginIcon);
notifactionView.setImageViewBitmap(R.id.cl_plugin_icon, pluginIcon);
notifactionView.setTextViewText(R.id.dl_plugin_msg, pluginContent);
Notification notification = mBuilder.build();
int id = 199;
LogUtils.d(TAG, "創(chuàng)建通知");
mNotificationManager.notify(id, notification);
Notification的各種樣式
1) BigText樣式(Android 4.1以上)
a) 最大高度一般為256dp
b) 不是最新的通知時(shí)默認(rèn)為折疊狀態(tài)
c) 不設(shè)置SummaryText的話,展開(kāi)后最下面一行的內(nèi)容會(huì)消失
例子:
private void showBigViewText() {
NotificationCompat.BigTextStyle textStyle = new BigTextStyle();
textStyle
.setBigContentTitle("BigContentTitle")
.setSummaryText("SummaryText")
.bigText(
"I am Big Text");
Notification notification = new NotificationCompat.Builder(context)
.setLargeIcon(icon).setSmallIcon(R.drawable.ic_launcher)
.setTicker("showBigView_Text").setContentInfo("contentInfo")
.setContentTitle("ContentTitle").setContentText("ContentText")
.setStyle(textStyle)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL)
.build();
manager.notify(NOTIFICATION_ID_2, notification);
}
2) Inbox樣式
a) 高度一般為256dp
b) 不是最新的通知時(shí)默認(rèn)為折疊狀態(tài)
c) 不設(shè)置SummaryText的話,展開(kāi)后最下面一行的內(nèi)容會(huì)消失
例子:
private void showBigViewInbox() {
NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
inboxStyle.setBigContentTitle("BigContentTitle").setSummaryText(
"SummaryText");
for (int i = 0; i < 5; i++)
inboxStyle.addLine("news:" + i);
Notification notification = new NotificationCompat.Builder(context)
.setLargeIcon(icon).setSmallIcon(R.drawable.ic_launcher)
.setTicker("showBigView_Inbox").setContentInfo("contentInfo")
.setContentTitle("ContentTitle").setContentText("ContentText")
.setStyle(inboxStyle)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL)
.build();
manager.notify(NOTIFICATION_ID_4, notification);
}
3) BigPicture樣式
a) 高度一般為256dp
b) 不是最新的通知時(shí)為默認(rèn)折疊狀態(tài)
c) 不設(shè)置SummaryText的話,展開(kāi)后第二行字的內(nèi)容會(huì)消失
例子:
private void showBigViewPic() {
NotificationCompat.BigPictureStyle pictureStyle = new BigPictureStyle();
pictureStyle.setBigContentTitle("BigContentTitle")
.setSummaryText("SummaryText").bigPicture(icon);
Notification notification = new NotificationCompat.Builder(context)
.setLargeIcon(icon).setSmallIcon(R.drawable.ic_launcher)
.setTicker("showBigView_Pic").setContentInfo("contentInfo")
.setContentTitle("ContentTitle").setContentText("ContentText")
.setStyle(pictureStyle)
.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL)
.build();
manager.notify(NOTIFICATION_ID_3, notification);
}
4) 折疊式Notification
折疊式Notification是一種自定義視圖的Notification,用來(lái)顯示長(zhǎng)文本和一些自定義的布局的場(chǎng)景。它有兩種狀態(tài),一種是普通狀態(tài)下的視圖,一種是展開(kāi)狀態(tài)下的視圖。和普通Notification不同的是,我們需要自定義的視圖,而這個(gè)視圖顯示的進(jìn)程和我們創(chuàng)建視圖的進(jìn)程不再一個(gè)進(jìn)程,所以我們需要使用RemoteViews,首先要使用RemoteViews來(lái)創(chuàng)建我們的自定義視圖:
//用RemoteViews來(lái)創(chuàng)建自定義Notification視圖
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view);
視圖的布局文件:
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="@drawable/fold"
android:orientation="horizontal">
android:id="@+id/iv_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/fold"
/>
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:layout_marginLeft="150dp"
android:text="展開(kāi)后的視圖"
android:textColor="@color/colorPrimaryDark"/>
把自定義視圖賦值給Notification展開(kāi)時(shí)的視圖
//指定展開(kāi)時(shí)的視圖
notification.bigContentView = remoteViews;
也可以把自定義視圖賦值給Notification普通狀態(tài)時(shí)的視圖
//指定普通狀態(tài)時(shí)的視圖
notification.contentView = remoteViews;
折疊式Notification完整代碼:
Notification.Builder builder = new Notification.Builder(this);
Intent mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://blog.csdn.net/itachi85/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mIntent, 0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.foldleft);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.lanucher));
builder.setAutoCancel(true);
builder.setContentTitle("折疊式通知");
//用RemoteViews來(lái)創(chuàng)建自定義Notification視圖
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.view_fold);
Notification notification = builder.build();
//指定展開(kāi)時(shí)的視圖
notification.bigContentView = remoteViews;
notificationManager.notify(1, notification);
5) 懸掛式Notification (5.0新增)
懸掛式Notification是android5.0新增加的方式,懸掛式Notification不需要下拉通知欄就直接顯示出來(lái)懸掛在屏幕上方并且焦點(diǎn)不變?nèi)栽谟脩舨僮鞯慕缑嬉虼瞬粫?huì)打斷用戶的操作,過(guò)幾秒就會(huì)自動(dòng)消失。他需要調(diào)用setFullScreenIntent來(lái)將Notification變?yōu)閼覓焓絅otification
//如果描述的PendingIntent已經(jīng)存在,則在產(chǎn)生新的Intent之前會(huì)先取消掉當(dāng)前的
PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, hangIntent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setFullScreenIntent(hangPendingIntent, true);
懸掛式Notification完整代碼:
Notification.Builder builder = new Notification.Builder(this);
Intent mIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://blog.csdn.net/itachi85/"));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mIntent, 0);
builder.setContentIntent(pendingIntent);
builder.setSmallIcon(R.drawable.foldleft);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.lanucher));
builder.setAutoCancel(true);
builder.setContentTitle("懸掛式通知");
//設(shè)置點(diǎn)擊跳轉(zhuǎn)
Intent hangIntent = new Intent();
hangIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
hangIntent.setClass(this, MyNotificationActivity.class);
//如果描述的PendingIntent已經(jīng)存在,則在產(chǎn)生新的Intent之前會(huì)先取消掉當(dāng)前的
PendingIntent hangPendingIntent = PendingIntent.getActivity(this, 0, hangIntent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setFullScreenIntent(hangPendingIntent, true);
notificationManager.notify(2, builder.build());
6) 鎖屏通知
Android 5.0(API level 21)開(kāi)始,通知可以顯示在鎖屏上。用戶可以通過(guò)設(shè)置選擇是否允許敏感的通知內(nèi)容顯示在安全的鎖屏上。你的應(yīng)用可以通過(guò)setVisibility()控制通知的顯示等級(jí):
VISIBILITY_PRIVATE : 顯示基本信息,如通知的圖標(biāo),但隱藏通知的全部?jī)?nèi)容
VISIBILITY_PUBLIC : 顯示通知的全部?jī)?nèi)容
VISIBILITY_SECRET : 不顯示任何內(nèi)容,包括圖標(biāo)
builder.setVisibility(Notification.VISIBILITY_PUBLIC);