Notification

社會(huì)樹狀圖

基本使用

1.獲取 NotificationManager 實(shí)例
2.實(shí)例化 NotificationCompat.Builder 并設(shè)置相關(guān)屬性
3.通過 builder.build() 方法生成 Notification 對(duì)象,并發(fā)送通知

  //獲取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());
   //通過builder.build()方法生成Notification對(duì)象,并發(fā)送通知,id=1
   notifyManager.notify(1, builder.build());

ps

setSmallIcon()和 setLargeIcon()同時(shí)存在的時(shí)候
小logo在通知欄的右下方

實(shí)行交互功能

即點(diǎn)擊轉(zhuǎn)跳

/**
* 發(fā)送一個(gè)點(diǎn)擊跳轉(zhuǎn)到MainActivity的消息
*/
private void sendSimplestNotificationWithAction() {
   //獲取PendingIntent
   Intent mainIntent = new Intent(this, MainActivity.class);
   PendingIntent mainPendingIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
   //創(chuàng)建 Notification.Builder 對(duì)象
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           //點(diǎn)擊通知后自動(dòng)清除
           .setAutoCancel(true)
           .setContentTitle("我是帶Action的Notification")
           .setContentText("點(diǎn)我會(huì)打開MainActivity")
           .setContentIntent(mainPendingIntent);
   //發(fā)送通知
   mNotifyManager.notify(3, builder.build());
}

這里注意三個(gè)Intent (Intent PendingIntent 以及方法setContentIntent() ) 接下來重點(diǎn)介紹PendingIntent

pendingIntent

pendingIntent即一個(gè)延遲的Intent ,就是用戶點(diǎn)擊通知的時(shí)候才會(huì)執(zhí)行,

PendingIntent 是 Android 系統(tǒng)管理并持有的用于描述和獲取原始數(shù)據(jù)的對(duì)象的標(biāo)志(引用)。也就是說,即便創(chuàng)建該P(yáng)endingIntent對(duì)象的進(jìn)程被殺死了,這個(gè)PendingItent對(duì)象在其他進(jìn)程中還是可用的。
日常使用中的短信、鬧鐘等都用到了 PendingIntent。(引用

pendingIntent的獲取方式

//獲取一個(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)

PengdingIntent有幾種flag

FLAG_CANCEL_CURRENT:如果系統(tǒng)存在一個(gè)相同的PendingIntent的,取消之前的對(duì)象再新創(chuàng)建一個(gè)PendingIntent對(duì)象

FLAG_NO_CREATE:如果系統(tǒng)中不存在這個(gè)PengdingIntent對(duì)象時(shí),返回null

FLAG_ONE_SHOT:給PendingIntent只作用一次

FLAG_UPDATE_CURRENT:如果系統(tǒng)中已存在該 PendingIntent 對(duì)象,那么系統(tǒng)將保留該 PendingIntent 對(duì)象,但是會(huì)使用新的 Intent 來更新之前 PendingIntent 中的 Intent 對(duì)象數(shù)據(jù),例如更新 Intent 中的 Extras 。(!!!!!)

PengdingIntent的更新

更新通知即發(fā)送新的通知即可,只要ID相同即可,
如果更新存在的畫只是改變,
如果被取消即創(chuàng)建新的通知;

取消 PendingIntent(五種)

  • 通知被清除 按鈕 右滑
  • 設(shè)置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,點(diǎn)擊該通知時(shí)會(huì)清除它
  • 調(diào)用NotificationManagerCancel(int id) 指定Id消除
  • 通過 NotificationManager 調(diào)用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
  • 通過 NotificationManager 調(diào)用 cancelAll() 方法清除所有該應(yīng)用之前發(fā)送的通知

    小Demo

/**
 * 為了方便,大部分通知都沒設(shè)置對(duì)應(yīng)的Action,即PendingIntent
 * 除了sendFlagAutoCancelNotification()方法
 */
public class SimpleNotificationActivity extends Activity implements View.OnClickListener {

    //Notification.FLAG_FOREGROUND_SERVICE    //表示正在運(yùn)行的服務(wù)
    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:
                //移除當(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)清除,但能通過 cancel() 方法清除
     * Notification.flags屬性可以通過 |= 運(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)清除,但能通過 cancel() 方法清除
        //flags 可以通過 |= 運(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)清除,但能通過 cancel() 方法清除
        //等價(jià)于 builder.setOngoing(true);
        notification.flags |= Notification.FLAG_ONGOING_EVENT;
        mNotificationManager.notify(DEFAULT_NOTIFICATION_ID, notification);
    }    
}

Notification實(shí)現(xiàn)通知功能

用setDefaults()方法來實(shí)現(xiàn)相關(guān)通知功能
ps:一旦設(shè)置了Defaluts效果則 ,自定義效果就會(huì)消失

這幾個(gè)事默認(rèn)設(shè)置

//設(shè)置系統(tǒng)默認(rèn)提醒效果,一旦設(shè)置默認(rèn)提醒效果,則自定義的提醒效果會(huì)全部失效。具體可看源碼
//添加默認(rèn)震動(dòng)效果,需要申請(qǐng)震動(dòng)權(quán)限
//<uses-permission android:name="android.permission.VIBRATE" />
Notification.DEFAULT_VIBRATE

//添加系統(tǒng)默認(rèn)聲音效果,設(shè)置此值后,調(diào)用setSound()設(shè)置自定義聲音無效
Notification.DEFAULT_SOUND

//添加默認(rèn)呼吸燈效果,使用時(shí)須與 Notification.FLAG_SHOW_LIGHTS 結(jié)合使用,否則無效
Notification.DEFAULT_LIGHTS

//添加上述三種默認(rèn)提醒效果
Notification.DEFAULT_ALL```
此為未有默認(rèn)設(shè)置的

```java
//提醒效果常用 Flag
//三色燈提醒,在使用三色燈提醒時(shí)候必須加該標(biāo)志符
Notification.FLAG_SHOW_LIGHTS

//發(fā)起正在運(yùn)行事件(活動(dòng)中)
Notification.FLAG_ONGOING_EVENT
//FLAG_ONGOING_EVENT 表示該通知通知放置在正在運(yùn)行,不能被手動(dòng)清除,但能通過 cancel() 方法清除

//讓聲音、振動(dòng)無限循環(huán),直到用戶響應(yīng) (取消或者打開)
Notification.FLAG_INSISTENT

//發(fā)起Notification后,鈴聲和震動(dòng)均只執(zhí)行一次
Notification.FLAG_ONLY_ALERT_ONCE

//用戶單擊通知后自動(dòng)消失
Notification.FLAG_AUTO_CANCEL

//只有調(diào)用NotificationManager.cancel()時(shí)才會(huì)清除
Notification.FLAG_NO_CLEAR

//表示正在運(yùn)行的服務(wù)
Notification.FLAG_FOREGROUND_SERVICE```
接下來講講核心代碼
```java
/**
* 最普通的通知效果
*/
private void showNotifyOnlyText() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setLargeIcon(mLargeIcon)
           .setContentTitle("我是只有文字效果的通知")
           .setContentText("我沒有鈴聲、震動(dòng)、呼吸燈,但我就是一個(gè)通知");
   mManager.notify(1, builder.build());
}

/**
* 展示有自定義鈴聲效果的通知
* 補(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("美妙么?安靜聽~")
           //調(diào)用系統(tǒng)默認(rèn)響鈴,設(shè)置此屬性后setSound()會(huì)無效
           //.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());
}

/**
* 展示有震動(dòng)效果的通知,需要在AndroidManifest.xml中申請(qǐng)震動(dòng)權(quán)限
* <uses-permission android:name="android.permission.VIBRATE" />
* 補(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());
}

/**
* 顯示帶有呼吸燈效果的通知,但是不知道為什么,自己這里測(cè)試沒成功
*/
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);
}

/**
* 顯示帶有默認(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("我是最棒的~")
           //等價(jià)于setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE);
           .setDefaults(Notification.DEFAULT_ALL);
   mManager.notify(5, builder.build());
}

/**
* 通知無限循環(huán),直到用戶取消或者打開通知欄(其實(shí)觸摸就可以了),效果與FLAG_ONLY_ALERT_ONCE相反
* 注:這里沒有給Notification設(shè)置PendingIntent,也就是說該通知無法響應(yīng),所以只能手動(dòng)取消
*/
private void showInsistentNotify() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("我是一個(gè)死循環(huán),除非你取消或者響應(yīng)")
           .setContentText("啦啦啦~")
           .setDefaults(Notification.DEFAULT_ALL);
   Notification notify = builder.build();
   notify.flags |= Notification.FLAG_INSISTENT;
   mManager.notify(6, notify);
}

/**
* 通知只執(zhí)行一次,與默認(rèn)的效果一樣
*/
private void showAlertOnceNotify() {
   NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
           .setSmallIcon(R.mipmap.ic_launcher)
           .setContentTitle("仔細(xì)看,我就執(zhí)行一遍")
           .setContentText("好了,已經(jīng)一遍了~")
           .setDefaults(Notification.DEFAULT_ALL);
   Notification notify = builder.build();
   notify.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
   mManager.notify(7, notify);
}

/**
* 清除所有通知
*/
private void clearNotify() {
   mManager.cancelAll();
}```
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容