社會樹狀圖
基本使用
1.獲取 NotificationManager 實例
2.實例化 NotificationCompat.Builder 并設置相關屬性
3.通過 builder.build() 方法生成 Notification 對象,并發送通知
//獲取NotificationManager實例
NotificationManager notifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//實例化NotificationCompat.Builde并設置相關屬性
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
//設置小圖標
.setSmallIcon(R.mipmap.icon_fab_repair)
//設置通知標題
.setContentTitle("最簡單的Notification")
//設置通知內容
.setContentText("只有小圖標、標題、內容")
//設置通知時間,默認為系統發出通知的時間,通常不用設置
//.setWhen(System.currentTimeMillis());
//通過builder.build()方法生成Notification對象,并發送通知,id=1
notifyManager.notify(1, builder.build());
ps
setSmallIcon()和 setLargeIcon()同時存在的時候
小logo在通知欄的右下方
實行交互功能
即點擊轉跳
/**
* 發送一個點擊跳轉到MainActivity的消息
*/
private void sendSimplestNotificationWithAction() {
//獲取PendingIntent
Intent mainIntent = new Intent(this, MainActivity.class);
PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
//創建 Notification.Builder 對象
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
//點擊通知后自動清除
.setAutoCancel(true)
.setContentTitle("我是帶Action的Notification")
.setContentText("點我會打開MainActivity")
.setContentIntent(mainPendingIntent);
//發送通知
mNotifyManager.notify(3, builder.build());
}
這里注意三個Intent (Intent PendingIntent 以及方法setContentIntent() ) 接下來重點介紹PendingIntent
pendingIntent
pendingIntent即一個延遲的Intent ,就是用戶點擊通知的時候才會執行,
PendingIntent 是 Android 系統管理并持有的用于描述和獲取原始數據的對象的標志(引用)。也就是說,即便創建該PendingIntent對象的進程被殺死了,這個PendingItent對象在其他進程中還是可用的。
日常使用中的短信、鬧鐘等都用到了 PendingIntent。(引用)
pendingIntent的獲取方式
//獲取一個用于啟動 Activity 的 PendingIntent 對象
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags);
//獲取一個用于啟動 Service 的 PendingIntent 對象
public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags);
//獲取一個用于向 BroadcastReceiver 廣播的 PendingIntent 對象
public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
PengdingIntent有幾種flag
FLAG_CANCEL_CURRENT:如果系統存在一個相同的PendingIntent的,取消之前的對象再新創建一個PendingIntent對象
FLAG_NO_CREATE:如果系統中不存在這個PengdingIntent對象時,返回null
FLAG_ONE_SHOT:給PendingIntent只作用一次
FLAG_UPDATE_CURRENT:如果系統中已存在該 PendingIntent 對象,那么系統將保留該 PendingIntent 對象,但是會使用新的 Intent 來更新之前 PendingIntent 中的 Intent 對象數據,例如更新 Intent 中的 Extras 。(!!!!!)
PengdingIntent的更新
更新通知即發送新的通知即可,只要ID相同即可,
如果更新存在的畫只是改變,
如果被取消即創建新的通知;
取消 PendingIntent(五種)
- 通知被清除 按鈕 右滑
- 設置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,點擊該通知時會清除它
- 調用NotificationManager的Cancel(int id) 指定Id消除
- 通過 NotificationManager 調用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
- 通過 NotificationManager 調用 cancelAll() 方法清除所有該應用之前發送的通知
小Demo
/**
* 為了方便,大部分通知都沒設置對應的Action,即PendingIntent
* 除了sendFlagAutoCancelNotification()方法
*/
public class SimpleNotificationActivity extends Activity implements View.OnClickListener {
//Notification.FLAG_FOREGROUND_SERVICE //表示正在運行的服務
public static final String NOTIFICATION_TAG = "littlejie";
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:
//移除當前 Context 下所有 Notification,包括 FLAG_NO_CLEAR 和 FLAG_ONGOING_EVENT
mNotificationManager.cancelAll();
break;
case R.id.btn_send_notification:
//發送一個 Notification,此處 ID = 1
sendNotification();
break;
case R.id.btn_remove_notification:
//移除 ID = 1 的 Notification,注意:該方法只針對當前 Context。
mNotificationManager.cancel(DEFAULT_NOTIFICATION_ID);
break;
case R.id.btn_send_notification_with_tag:
//發送一個 ID = 1 并且 TAG = littlejie 的 Notification
//注意:此處發送的通知與 sendNotification() 發送的通知并不沖突
//因為此處的 Notification 帶有 TAG
sendNotificationWithTag();
break;
case R.id.btn_remove_notification_with_tag:
//移除一個 ID = 1 并且 TAG = littlejie 的 Notification
//注意:此處移除的通知與 NotificationManager.cancel(int id) 移除通知并不沖突
//因為此處的 Notification 帶有 TAG
mNotificationManager.cancel(NOTIFICATION_TAG, DEFAULT_NOTIFICATION_ID);
break;
case R.id.btn_send_ten_notification:
//連續發十條 Notification
sendTenNotifications();
break;
case R.id.btn_send_flag_no_clear_notification:
//發送 ID = 1, flag = FLAG_NO_CLEAR 的 Notification
//下面兩個 Notification 的 ID 都為 1,會發現 ID 相等的 Notification 會被最新的替換掉
sendFlagNoClearNotification();
break;
case R.id.btn_send_flag_auto_cancecl_notification:
sendFlagOngoingEventNotification();
break;
case R.id.btn_send_flag_ongoing_event_notification:
sendFlagAutoCancelNotification();
break;
}
}
/**
* 發送最簡單的通知,該通知的ID = 1
*/
private void sendNotification() {
//這里使用 NotificationCompat 而不是 Notification ,因為 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)方法發送通知
* 移除對應通知需使用 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());
}
/**
* 循環發送十個通知
*/
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());
}
}
/**
* 設置FLAG_NO_CLEAR
* 該 flag 表示該通知不能被狀態欄的清除按鈕給清除掉,也不能被手動清除,但能通過 cancel() 方法清除
* Notification.flags屬性可以通過 |= 運算疊加效果
*/
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();
//設置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_NO_CLEAR 表示該通知不能被狀態欄的清除按鈕給清除掉,也不能被手動清除,但能通過 cancel() 方法清除
//flags 可以通過 |= 運算疊加效果
notification.flags |= Notification.FLAG_NO_CLEAR;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
/**
* 設置FLAG_AUTO_CANCEL
* 該 flag 表示用戶單擊通知后自動消失
*/
private void sendFlagAutoCancelNotification() {
//設置一個Intent,不然點擊通知不會自動消失
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();
//設置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_AUTO_CANCEL 表示該通知能被狀態欄的清除按鈕給清除掉
//等價于 builder.setAutoCancel(true);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
/**
* 設置FLAG_ONGOING_EVENT
* 該 flag 表示發起正在運行事件(活動中)
*/
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();
//設置 Notification 的 flags = FLAG_NO_CLEAR
//FLAG_ONGOING_EVENT 表示該通知通知放置在正在運行,不能被手動清除,但能通過 cancel() 方法清除
//等價于 builder.setOngoing(true);
notification.flags |= Notification.FLAG_ONGOING_EVENT;
mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
}
}
Notification實現通知功能
用setDefaults()方法來實現相關通知功能
ps:一旦設置了Defaluts效果則 ,自定義效果就會消失
這幾個事默認設置
//設置系統默認提醒效果,一旦設置默認提醒效果,則自定義的提醒效果會全部失效。具體可看源碼
//添加默認震動效果,需要申請震動權限
//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE
//添加系統默認聲音效果,設置此值后,調用setSound()設置自定義聲音無效
Notification.DEFAULT_SOUND
//添加默認呼吸燈效果,使用時須與 Notification.FLAG_SHOW_LIGHTS 結合使用,否則無效
Notification.DEFAULT_LIGHTS
//添加上述三種默認提醒效果
Notification.DEFAULT_ALL```
此為未有默認設置的
```java
//提醒效果常用 Flag
//三色燈提醒,在使用三色燈提醒時候必須加該標志符
Notification.FLAG_SHOW_LIGHTS
//發起正在運行事件(活動中)
Notification.FLAG_ONGOING_EVENT
//FLAG_ONGOING_EVENT 表示該通知通知放置在正在運行,不能被手動清除,但能通過 cancel() 方法清除
//讓聲音、振動無限循環,直到用戶響應 (取消或者打開)
Notification.FLAG_INSISTENT
//發起Notification后,鈴聲和震動均只執行一次
Notification.FLAG_ONLY_ALERT_ONCE
//用戶單擊通知后自動消失
Notification.FLAG_AUTO_CANCEL
//只有調用NotificationManager.cancel()時才會清除
Notification.FLAG_NO_CLEAR
//表示正在運行的服務
Notification.FLAG_FOREGROUND_SERVICE```
接下來講講核心代碼
```java
/**
* 最普通的通知效果
*/
private void showNotifyOnlyText() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(mLargeIcon)
.setContentTitle("我是只有文字效果的通知")
.setContentText("我沒有鈴聲、震動、呼吸燈,但我就是一個通知");
mManager.notify(1, builder.build());
}
/**
* 展示有自定義鈴聲效果的通知
* 補充:使用系統自帶的鈴聲效果: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("美妙么?安靜聽~")
//調用系統默認響鈴,設置此屬性后setSound()會無效
//.setDefaults(Notification.DEFAULT_SOUND)
//調用系統多媒體褲內的鈴聲
//.setSound(Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"));
//調用自己提供的鈴聲,位于 /res/values/raw 目錄下
.setSound(Uri.parse("android.resource://com.littlejie.notification/" + R.raw.sound));
//另一種設置鈴聲的方法
//Notification notify = builder.build();
//調用系統默認鈴聲
//notify.defaults = Notification.DEFAULT_SOUND;
//調用自己提供的鈴聲
//notify.sound = Uri.parse("android.resource://com.littlejie.notification/"+R.raw.sound);
//調用系統自帶的鈴聲
//notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2");
//mManager.notify(2,notify);
mManager.notify(2, builder.build());
}
/**
* 展示有震動效果的通知,需要在AndroidManifest.xml中申請震動權限
* <uses-permission android:name="android.permission.VIBRATE" />
* 補充:測試震動的時候,手機的模式一定要調成鈴聲+震動模式,否則你是感受不到震動的
*/
private void showNotifyWithVibrate() {
//震動也有兩種設置方法,與設置鈴聲一樣,在此不再贅述
long[] vibrate = new long[]{0, 500, 1000, 1500};
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是伴有震動效果的通知")
.setContentText("顫抖吧,凡人~")
//使用系統默認的震動參數,會與自定義的沖突
//.setDefaults(Notification.DEFAULT_VIBRATE)
//自定義震動效果
.setVibrate(vibrate);
//另一種設置震動的方法
//Notification notify = builder.build();
//調用系統默認震動
//notify.defaults = Notification.DEFAULT_VIBRATE;
//調用自己設置的震動
//notify.vibrate = vibrate;
//mManager.notify(3,notify);
mManager.notify(3, builder.build());
}
/**
* 顯示帶有呼吸燈效果的通知,但是不知道為什么,自己這里測試沒成功
*/
private void showNotifyWithLights() {
final NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是帶有呼吸燈效果的通知")
.setContentText("一閃一閃亮晶晶~")
//ledARGB 表示燈光顏色、 ledOnMS 亮持續時間、ledOffMS 暗的時間
.setLights(0xFF0000, 3000, 3000);
Notification notify = builder.build();
//只有在設置了標志符Flags為Notification.FLAG_SHOW_LIGHTS的時候,才支持呼吸燈提醒。
notify.flags = Notification.FLAG_SHOW_LIGHTS;
//設置lights參數的另一種方式
//notify.ledARGB = 0xFF0000;
//notify.ledOnMS = 500;
//notify.ledOffMS = 5000;
//使用handler延遲發送通知,因為連接usb時,呼吸燈一直會亮著
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
mManager.notify(4, builder.build());
}
}, 10000);
}
/**
* 顯示帶有默認鈴聲、震動、呼吸燈效果的通知
* 如需實現自定義效果,請參考前面三個例子
*/
private void showNotifyWithMixed() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是有鈴聲+震動+呼吸燈效果的通知")
.setContentText("我是最棒的~")
//等價于setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
.setDefaults(Notification.DEFAULT_ALL);
mManager.notify(5, builder.build());
}
/**
* 通知無限循環,直到用戶取消或者打開通知欄(其實觸摸就可以了),效果與FLAG_ONLY_ALERT_ONCE相反
* 注:這里沒有給Notification設置PendingIntent,也就是說該通知無法響應,所以只能手動取消
*/
private void showInsistentNotify() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("我是一個死循環,除非你取消或者響應")
.setContentText("啦啦啦~")
.setDefaults(Notification.DEFAULT_ALL);
Notification notify = builder.build();
notify.flags |= Notification.FLAG_INSISTENT;
mManager.notify(6, notify);
}
/**
* 通知只執行一次,與默認的效果一樣
*/
private void showAlertOnceNotify() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("仔細看,我就執行一遍")
.setContentText("好了,已經一遍了~")
.setDefaults(Notification.DEFAULT_ALL);
Notification notify = builder.build();
notify.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
mManager.notify(7, notify);
}
/**
* 清除所有通知
*/
private void clearNotify() {
mManager.cancelAll();
}```