摘要:當(dāng)向系統(tǒng)發(fā)出通知時,它將先以圖標(biāo)的形式顯示在通知欄中。通知欄和抽屜式通知欄均是由系統(tǒng)控制,用戶可以隨時查看。更新通知跟發(fā)送通知使用相同的方式。創(chuàng)建返回棧添加返回棧代碼默認(rèn)情況下,從通知啟動一個,按返回鍵會回到主屏幕。
目錄介紹
1.Notification簡單概述
2.Notification通知用途
3.Notification的基本操作
3.1 Notification創(chuàng)建必要的屬性
3.2 Notification簡單創(chuàng)建步驟
3.3 關(guān)于setSmallIcon()與setLargeIcon()區(qū)別
3.4 Notification的Action屬性【交互作用】
3.5 更新Notification
3.6 取消Notification
3.7 設(shè)置flag屬性
3.8 設(shè)置Notification的通知效果
3.9 設(shè)置自定義Notification通知欄布局
4.Notification相關(guān)屬性說明
4.1 PendingIntent說明
4.2 創(chuàng)建返回棧PendingIntent
4.3 注意要點
5.部分源碼分析思考
5.1 RemoteView是什么?
5.2 查看源碼,了解Notification如何創(chuàng)建布局
6.關(guān)于Android8.0通知欄適配
6.1 Android O(8.0)通知的改變
6.2 報錯內(nèi)容和解決方案
6.3 最終解決方案
7.關(guān)于其他
好消息已經(jīng)解決了8.0以上通知欄不能顯示問題。封裝成了lib庫,歡迎大家下載。已經(jīng)放到正式項目運(yùn)行多時!
項目地址鏈接:https://github.com/yangchong2...
本篇文章已授權(quán)微信公眾號 guolin_blog (郭霖)獨(dú)家發(fā)布
項目截圖說明
1.Notification簡單概述Notification,是一種具有全局效果的通知,可以在系統(tǒng)的通知欄中顯示。當(dāng) APP 向系統(tǒng)發(fā)出通知時,它將先以圖標(biāo)的形式顯示在通知欄中。用戶可以下拉通知欄查看通知的詳細(xì)信息。通知欄和抽屜式通知欄均是由系統(tǒng)控制,用戶可以隨時查看。
2.Notification通知用途常見的用途
顯示接收到短消息、及時消息等信息(如QQ、微信、新浪、短信)
顯示客戶端的推送消息,如廣告、優(yōu)惠、版本更新、推薦新聞等,常用的第三方 SDK 有: JPush 、 個推 、 信鴿 、 網(wǎng)易云信(偏重 IM ) 、 阿里云推送
顯示正在進(jìn)行的事物,例如:后臺運(yùn)行的程序,如音樂播放進(jìn)度、下載進(jìn)度等
前兩點可以歸結(jié)為與用戶交互,第三點是實時的任務(wù)提醒,但不可否認(rèn)的是,第三點也會與用戶交互。
3.Notification的基本操作3.1 Notification創(chuàng)建必要的屬性,必須設(shè)置
3.1.1 必須添加的屬性
小圖標(biāo),通過 setSmallIcon() 方法設(shè)置
標(biāo)題,通過 setContentTitle() 方法設(shè)置
內(nèi)容,通過 setContentText() 方法設(shè)置
3.2 Notification創(chuàng)建步驟
3.2.1 Notification 的創(chuàng)建主要涉及到 Notification.Builder 、 Notification 、 NotificationManager
Notification.Builer : 使用建造者模式構(gòu)建 Notification 對象。由于 Notification.Builder 僅支持 Android 4.1及之后的版本,為了解決兼容性問題, Google 在 Android Support v4 中加入了 - NotificationCompat.Builder 類。對于某些在 Android 4.1 之后才特性,即使 NotificationCompat.Builder 支持該方法,在之前的版本中也不能運(yùn)行。
Notification : 通知對應(yīng)類,保存通知相關(guān)的數(shù)據(jù)。- NotificationManager 向系統(tǒng)發(fā)送通知時會用到。
NotificationManager : NotificationManager 是通知管理類,它是一個系統(tǒng)服務(wù)。調(diào)用 NotificationManager 的 notify() 方法可以向系統(tǒng)發(fā)送通知。
3.2.2 Notification創(chuàng)建步驟與代碼
// 創(chuàng)建一個NotificationManager的引用 NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); // 定義Notification的各種屬性 Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext()) .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI) // .setSmallIcon(R.mipmap.ic_launcher) //設(shè)置通知的圖標(biāo) .setTicker("有新消息呢") //設(shè)置狀態(tài)欄的標(biāo)題 .setContentTitle("這個是標(biāo)題") //設(shè)置標(biāo)題 .setContentText("這個是內(nèi)容") //消息內(nèi)容 .setDefaults(Notification.DEFAULT_ALL) //設(shè)置默認(rèn)的提示音 .setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知的優(yōu)先級 .setOngoing(false) //讓通知左右滑的時候不能取消通知 .setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知的優(yōu)先級 .setWhen(System.currentTimeMillis()) //設(shè)置通知時間,默認(rèn)為系統(tǒng)發(fā)出通知的時間,通常不用設(shè)置 .setAutoCancel(true); //打開程序后圖標(biāo)消失 //處理點擊Notification的邏輯 Intent resultIntent = new Intent(this, TestActivity.class); resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //添加為棧頂Activity resultIntent.putExtra("what",5); PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); //發(fā)送 mNotificationManager.notify(1, mBuilder.build()); //結(jié)束廣播 //mNotificationManager.cancel(1);
3.3 關(guān)于setSmallIcon()與setLargeIcon()區(qū)別
在 NotificationCompat.Builder 中有設(shè)置通知的大小圖標(biāo)的兩個方法。這兩個方法有什么區(qū)別呢?
當(dāng) setSmallIcon() 與 setLargeIcon() 同時存在時, smallIcon 顯示在通知的右下角, largeIcon 顯示在左側(cè)
當(dāng)只設(shè)置 setSmallIcon() 時, smallIcon 顯示在左側(cè)??聪聢D你就明白了。
對于部分 ROM ,可能修改過源碼,如 MIUI 上通知的大圖標(biāo)和小圖標(biāo)是沒有區(qū)別的。
效果如圖所示:
3.4 Notification的Action屬性
設(shè)置一個 Action ,這樣就可以直接跳轉(zhuǎn)到 App 的某個 Activity 、啟動一個 Service 或者發(fā)送一個 Broadcast。否則,Notification 僅僅只能起到通知的效果,而不能與用戶交互。
具體代碼如下所示:
//創(chuàng)建intent Intent resultIntent = new Intent(this, TestActivity.class); resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //添加為棧頂Activity resultIntent.putExtra("what",5); PendingIntent resultPendingIntent = PendingIntent.getActivity(this,5,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT); //發(fā)送pendingIntent mBuilder.setContentIntent(resultPendingIntent);
3.5 更新Notification
更新通知很簡單,只需要再次發(fā)送相同 ID 的通知即可,如果之前的通知還未被取消,則會直接更新該通知相關(guān)的屬性;如果之前的通知已經(jīng)被取消,則會重新創(chuàng)建一個新通知。更新通知跟發(fā)送通知使用相同的方式。
3.6 取消Notification
取消通知有如下 5 種方式:
點擊通知欄的清除按鈕,會清除所有可清除的通知
設(shè)置了 setAutoCancel() 或 FLAG_AUTO_CANCEL 的通知,點擊該通知時會清除它
通過 NotificationManager 調(diào)用 cancel(int id) 方法清除指定 ID 的通知
通過 NotificationManager 調(diào)用 cancel(String tag, int id) 方法清除指定 TAG 和 ID 的通知
通過 NotificationManager 調(diào)用 cancelAll() 方法清除所有該應(yīng)用之前發(fā)送的通知
注意事項
如果你是通過 NotificationManager.notify(String tag, int id, Notification notify) 方法創(chuàng)建的通知,那么只能通過 NotificationManager.cancel(String tag, int id) 方法才能清除對應(yīng)的通知,調(diào)用NotificationManager.cancel(int id) 無效。
3.7 設(shè)置flag屬性
設(shè)置FLAG_NO_CLEAR表示
設(shè)置通知不能被狀態(tài)欄的清除按鈕給清除掉,也不能被手動清除,但能通過 cancel() 方法清除
代碼:
private void sendNotification9() { Notification.Builder mBuilder = new Notification.Builder(this.getApplicationContext()) .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI) .setSmallIcon(R.mipmap.ic_launcher) //設(shè)置通知的圖標(biāo) .setTicker("有新消息呢9") //設(shè)置狀態(tài)欄的標(biāo)題 .setContentTitle("這個是標(biāo)題9") //設(shè)置標(biāo)題 .setContentText("這個是內(nèi)容9") //消息內(nèi)容 .setDefaults(Notification.DEFAULT_ALL) //設(shè)置默認(rèn)的提示音 .setOngoing(false) //讓通知左右滑的時候不能取消通知 .setAutoCancel(true); //打開程序后圖標(biāo)消失 Notification notification = mBuilder.build(); //設(shè)置 Notification 的 flags = FLAG_NO_CLEAR //FLAG_NO_CLEAR 表示該通知不能被狀態(tài)欄的清除按鈕給清除掉,也不能被手動清除,但能通過 cancel() 方法清除 //flags 可以通過 |= 運(yùn)算疊加效果 notification.flags |= Notification.FLAG_NO_CLEAR; //獲取NotificationManager 對象 mNotificationManager.notify(9, notification); } //取消通知: if(mNotificationManager!=null){ mNotificationManager.cancelAll(); }
3.8 設(shè)置Notification的通知效果
Notification 有震動、響鈴、呼吸燈三種響鈴效果,可以通過 setDefaults(int defualts) 方法來設(shè)置。 Default 屬性有以下四種,一旦設(shè)置了 Default 效果,自定義的效果就會失效。樓主在這里踩了坑,愣是調(diào)了半天沒找到為什么自定義效果會消失,忘大家慎之。
//設(shè)置系統(tǒng)默認(rèn)提醒效果,一旦設(shè)置默認(rèn)提醒效果,則自定義的提醒效果會全部失效。具體可看源碼//添加默認(rèn)震動效果,需要申請震動權(quán)限//Notification.DEFAULT_VIBRATE //添加系統(tǒng)默認(rèn)聲音效果,設(shè)置此值后,調(diào)用setSound()設(shè)置自定義聲音無效 Notification.DEFAULT_SOUND //添加默認(rèn)呼吸燈效果,使用時須與 Notification.FLAG_SHOW_LIGHTS 結(jié)合使用,否則無效 Notification.DEFAULT_LIGHTS //添加上述三種默認(rèn)提醒效果 Notification.DEFAULT_ALL
除了以上幾種設(shè)置 Notification 默認(rèn)通知效果,還可以通過以下幾種 FLAG 設(shè)置通知效果。
//提醒效果常用 Flag//三色燈提醒,在使用三色燈提醒時候必須加該標(biāo)志符 Notification.FLAG_SHOW_LIGHTS //發(fā)起正在運(yùn)行事件(活動中) Notification.FLAG_ONGOING_EVENT //讓聲音、振動無限循環(huán),直到用戶響應(yīng) (取消或者打開) Notification.FLAG_INSISTENT //發(fā)起Notification后,鈴聲和震動均只執(zhí)行一次 Notification.FLAG_ONLY_ALERT_ONCE //用戶單擊通知后自動消失 Notification.FLAG_AUTO_CANCEL //只有調(diào)用NotificationManager.cancel()時才會清除 Notification.FLAG_NO_CLEAR //表示正在運(yùn)行的服務(wù) Notification.FLAG_FOREGROUND_SERVICE
設(shè)置默認(rèn)提醒
// 添加默認(rèn)聲音提醒 builder.setDefaults(Notification.DEFAULT_SOUND); // 添加默認(rèn)呼吸燈提醒,自動添加FLAG_SHOW_LIGHTS builder.setDefaults(Notification.DEFAULT_LIGHTS);
設(shè)置鈴聲屬性,用的很少
private void sendNotification11() { Notification.Builder builder = new Notification.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("我是伴有鈴聲效果的通知11") .setContentText("美妙么?安靜聽~11") //調(diào)用系統(tǒng)默認(rèn)響鈴,設(shè)置此屬性后setSound()會無效 //.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.yc.cn.ycnotification/" + R.raw.hah)); //另一種設(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.yc.cn.ycnotification/"+R.raw.sound); //調(diào)用系統(tǒng)自帶的鈴聲 //notify.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"2"); //mManager.notify(11,notify); mNotificationManager.notify(11, builder.build()); }
設(shè)置震動屬性
private void sendNotification12() { //震動也有兩種設(shè)置方法,與設(shè)置鈴聲一樣,在此不再贅述 long[] vibrate = new long[]{0, 500, 1000, 1500}; Notification.Builder builder = new Notification.Builder(this) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("我是伴有震動效果的通知") .setContentText("顫抖吧,逗比哈哈哈哈哈~") //使用系統(tǒng)默認(rèn)的震動參數(shù),會與自定義的沖突 //.setDefaults(Notification.DEFAULT_VIBRATE) //自定義震動效果 .setVibrate(vibrate); //另一種設(shè)置震動的方法 //Notification notify = builder.build(); //調(diào)用系統(tǒng)默認(rèn)震動 //notify.defaults = Notification.DEFAULT_VIBRATE; //調(diào)用自己設(shè)置的震動 //notify.vibrate = vibrate; //mManager.notify(3,notify); mNotificationManager.notify(12, builder.build()); }
3.9 設(shè)置自定義Notification通知欄布局
代碼如下,注意,這里只取部分代碼,完整代碼可以下載github的完整項目:https://github.com/yangchong2...
.setContent(getRemoteViews()) // 設(shè)置通知欄的布局 //創(chuàng)建自定義布局 private RemoteViews getRemoteViews() { RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_mobile_play); // 設(shè)置 點擊通知欄的上一首按鈕時要執(zhí)行的意圖 remoteViews.setOnClickPendingIntent(R.id.btn_pre, getActivityPendingIntent(11)); // 設(shè)置 點擊通知欄的下一首按鈕時要執(zhí)行的意圖 remoteViews.setOnClickPendingIntent(R.id.btn_next, getActivityPendingIntent(12)); // 設(shè)置 點擊通知欄的播放暫停按鈕時要執(zhí)行的意圖 remoteViews.setOnClickPendingIntent(R.id.btn_start, getActivityPendingIntent(13)); // 設(shè)置 點擊通知欄的根容器時要執(zhí)行的意圖 remoteViews.setOnClickPendingIntent(R.id.ll_root, getActivityPendingIntent(14)); remoteViews.setTextViewText(R.id.tv_title, "標(biāo)題"); // 設(shè)置通知欄上標(biāo)題 remoteViews.setTextViewText(R.id.tv_artist, "藝術(shù)家"); // 設(shè)置通知欄上藝術(shù)家 return remoteViews; }4.Notification相關(guān)屬性說明
4.1 PendingIntent說明
4.1.1 PendingIntent基本說明
PendingIntent 是一種特殊的 Intent ,字面意思可以解釋為延遲的 Intent ,用于在某個事件結(jié)束后執(zhí)行特定的 Action 。從上面帶 Action 的通知也能驗證這一點,當(dāng)用戶點擊通知時,才會執(zhí)行。
PendingIntent 是 Android 系統(tǒng)管理并持有的用于描述和獲取原始數(shù)據(jù)的對象的標(biāo)志(引用)。也就是說,即便創(chuàng)建該P(yáng)endingIntent對象的進(jìn)程被殺死了,這個PendingItent對象在其他進(jìn)程中還是可用的。
日常使用中的短信、鬧鐘等都用到了 PendingIntent。
4.1.2 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)
4.1.3 PendingIntent具有幾種flag
FLAG_CANCEL_CURRENT:如果當(dāng)前系統(tǒng)中已經(jīng)存在一個相同的 PendingIntent 對象,那么就將先將已有的 PendingIntent 取消,然后重新生成一個 PendingIntent 對象。 FLAG_NO_CREATE:如果當(dāng)前系統(tǒng)中不存在相同的 PendingIntent 對象,系統(tǒng)將不會創(chuàng)建該 PendingIntent 對象而是直接返回 null 。 FLAG_ONE_SHOT:該 PendingIntent 只作用一次。 FLAG_UPDATE_CURRENT:如果系統(tǒng)中已存在該 PendingIntent 對象,那么系統(tǒng)將保留該 PendingIntent 對象,但是會使用新的 Intent 來更新之前 PendingIntent 中的 Intent 對象數(shù)據(jù),例如更新 Intent 中的 Extras 。
4.2 創(chuàng)建返回棧PendingIntent
4.2.1 添加返回棧代碼
默認(rèn)情況下,從通知啟動一個Activity,按返回鍵會回到主屏幕。
但某些時候有按返回鍵仍然留在當(dāng)前應(yīng)用的需求,這就要用到TaskStackBuilder了。
Notification.Builder mBuilder = new Notification.Builder(context) .setSound(android.provider.Settings.System.DEFAULT_NOTIFICATION_URI) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("廣播接受者標(biāo)題,小楊") .setContentText("廣播接受者內(nèi)容,扯犢子") .setAutoCancel(true); Log.i(TAG, "onReceive: intent" + intent.getClass().getName()); Intent resultIntent = new Intent(context, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); //將該Activity添加為棧頂 stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(resultPendingIntent); NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(1, mBuilder.build());
4.3 注意要點
如果用戶的手機(jī)使靜音模式,那么設(shè)置鈴聲或者震動效果將會失效
5.部分源碼分析思考5.1 RemoteView是什么?
5.1.1 什么是RemoteView?
為啥Notification不會設(shè)計成和普通View一樣的使用方式?理由很簡單!狀態(tài)欄不是單單由你的應(yīng)用程序管理.狀態(tài)欄是由Android系統(tǒng)管理的.你需要顯示Notification就必須和系統(tǒng)打交道.必須通過Notification服務(wù)才能顯示你的Notification.所以設(shè)計成用一個Notification實例代表一個Notification,然后通過notificationManager.notify函數(shù)提交給Notification服務(wù).
5.1.2 Notification服務(wù)是什么?是一個獨(dú)立的線程!
又扯出一個問題.跨線程顯示View.該怎么顯示?不是在本應(yīng)用程序顯示View.這里就要借用RemoteView.
RemoteView理解成對一個View的封裝,然后把RemoteView提交給其他線程.其他線程接收到RemoteView并且解析里面View的信息把它顯示出來.
5.1.3 在使用系統(tǒng)自帶的Notification系統(tǒng)會創(chuàng)建一個默認(rèn)的RemoteView!
系統(tǒng)默認(rèn)使用R.layout.notification_template_material_base生產(chǎn)一個RemoteView.
至于這里的布局是怎么查到的,請看下面源碼分析
5.2 查看源碼,了解Notification如何創(chuàng)建布局
5.2.1 首先看Notification中build代碼
5.2.2 然后看上圖中的createContentView()方法
5.2.3 然后看上圖中的createContentView()方法
6.關(guān)于Android8.0通知欄適配 6.1 Android O(8.0)通知的改變NotificationChannel是android8.0新增的特性,如果App的targetSDKVersion>=26,沒有設(shè)置channel通知渠道的話,就會導(dǎo)致通知無法展示。
Android O 引入了 通知渠道(Notification Channels),以提供統(tǒng)一的系統(tǒng)來幫助用戶管理通知,如果是針對 android O 為目標(biāo)平臺時,必須實現(xiàn)一個或者多個通知渠道,以向用戶顯示通知。比如聊天軟件,為每個聊天組設(shè)置一個通知渠道,指定特定聲音、燈光等配置。
6.2 報錯內(nèi)容和解決方案報錯內(nèi)容:Failed to post notification on channel “null” Target Api is 26
解決方案:
第一種:臨時方案,google也考慮到適配問題,臨時兼容方案是targetSDKVersion低于26
第二種:創(chuàng)建channel
6.3 最終解決方案
6.3.1 創(chuàng)建NotificationChannel步驟
創(chuàng)建NotificationChannel對象,指定Channel的id、name和通知的重要程度
使用NotificationMannager的createNotificationChannel方法來添加Channel。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上 createNotificationChannel(); } @TargetApi(Build.VERSION_CODES.O) private void createNotificationChannel() { NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); channel.canBypassDnd();//是否繞過請勿打擾模式 channel.enableLights(true);//閃光燈 channel.setLockscreenVisibility(VISIBILITY_SECRET);//鎖屏顯示通知 channel.setLightColor(Color.RED);//閃關(guān)燈的燈光顏色 channel.canShowBadge();//桌面launcher的消息角標(biāo) channel.enableVibration(true);//是否允許震動 channel.getAudioAttributes();//獲取系統(tǒng)通知響鈴聲音的配置 channel.getGroup();//獲取通知取到組 channel.setBypassDnd(true);//設(shè)置可繞過 請勿打擾模式 channel.setVibrationPattern(new long[]{100, 100, 200});//設(shè)置震動模式 channel.shouldShowLights();//是否會有燈光 getManager().createNotificationChannel(channel); }
設(shè)置通知重要性級別
該級別必須要在 NotificationChannel的構(gòu)造函數(shù)中指定,總共要五個級別;范圍是從NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4)
如果要支持 Android 7.1(API 25)及以下的設(shè)備,還得調(diào)用NotificationCompat 的 setPriority 方法來設(shè)置
6.3.2 用戶通知級別
Android 8.0 及以上是使用NotificationManager.IMPORTANCE_,
Android 7.1 及以下是使用NotificationCompat.PRIORITY_它們都是定義的常量
6.4 封裝的代碼
如下所示
public class NotificationUtils extends ContextWrapper { public static final String CHANNEL_ID = "default"; private static final String CHANNEL_NAME = "Default_Channel"; private NotificationManager mManager; private int[] flags; public NotificationUtils(Context base) { super(base); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上 createNotificationChannel(); } } @TargetApi(Build.VERSION_CODES.O) private void createNotificationChannel() { //第一個參數(shù):channel_id //第二個參數(shù):channel_name //第三個參數(shù):設(shè)置通知重要性級別 //注意:該級別必須要在 NotificationChannel 的構(gòu)造函數(shù)中指定,總共要五個級別; //范圍是從 NotificationManager.IMPORTANCE_NONE(0) ~ NotificationManager.IMPORTANCE_HIGH(4) NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); channel.canBypassDnd();//是否繞過請勿打擾模式 channel.enableLights(true);//閃光燈 channel.setLockscreenVisibility(VISIBILITY_SECRET);//鎖屏顯示通知 channel.setLightColor(Color.RED);//閃關(guān)燈的燈光顏色 channel.canShowBadge();//桌面launcher的消息角標(biāo) channel.enableVibration(true);//是否允許震動 channel.getAudioAttributes();//獲取系統(tǒng)通知響鈴聲音的配置 channel.getGroup();//獲取通知取到組 channel.setBypassDnd(true);//設(shè)置可繞過 請勿打擾模式 channel.setVibrationPattern(new long[]{100, 100, 200});//設(shè)置震動模式 channel.shouldShowLights();//是否會有燈光 getManager().createNotificationChannel(channel); } /** * 獲取創(chuàng)建一個NotificationManager的對象
*/ public NotificationManager getManager() { if (mManager == null) { mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); } return mManager; } /** * 清空所有的通知 */ public void clearNotification(){ getManager().cancelAll(); } /** * 建議使用這個發(fā)送通知 * 調(diào)用該方法可以發(fā)送通知 * @param notifyId notifyId * @param title title * @param content content */ public void sendNotification(int notifyId, String title, String content , int icon) { Notification build; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //android 8.0以上需要特殊處理,也就是targetSDKVersion為26以上 //通知用到NotificationCompat()這個V4庫中的方法。但是在實際使用時發(fā)現(xiàn)書上的代碼已經(jīng)過時并且Android8.0已經(jīng)不支持這種寫法 Notification.Builder builder = getChannelNotification(title, content, icon); build = builder.build(); } else { NotificationCompat.Builder builder = getNotificationCompat(title, content, icon); build = builder.build(); } if (flags!=null && flags.length>0){ for (int a=0 ; a項目地址鏈接:https://github.com/yangchong2... 關(guān)于其他內(nèi)容介紹 01.關(guān)于博客匯總鏈接0){ for (int a=0 ; a = Build.VERSION_CODES.O) { builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID); } else { //注意用下面這個方法,在8.0以上無法出現(xiàn)通知欄。8.0之前是正常的。這里需要增強(qiáng)判斷邏輯 builder = new NotificationCompat.Builder(getApplicationContext()); builder.setPriority(PRIORITY_DEFAULT); } builder.setContentTitle(title); builder.setContentText(content); builder.setSmallIcon(icon); builder.setPriority(priority); builder.setOnlyAlertOnce(onlyAlertOnce); builder.setOngoing(ongoing); if (remoteViews!=null){ builder.setContent(remoteViews); } if (intent!=null){ builder.setContentIntent(intent); } if (ticker!=null && ticker.length()>0){ builder.setTicker(ticker); } if (when!=0){ builder.setWhen(when); } if (sound!=null){ builder.setSound(sound); } if (defaults!=0){ builder.setDefaults(defaults); } //點擊自動刪除通知 builder.setAutoCancel(true); return builder; } @RequiresApi(api = Build.VERSION_CODES.O) private Notification.Builder getChannelNotification(String title, String content, int icon){ Notification.Builder builder = new Notification.Builder(getApplicationContext(), CHANNEL_ID); Notification.Builder notificationBuilder = builder //設(shè)置標(biāo)題 .setContentTitle(title) //消息內(nèi)容 .setContentText(content) //設(shè)置通知的圖標(biāo) .setSmallIcon(icon) //讓通知左右滑的時候是否可以取消通知 .setOngoing(ongoing) //設(shè)置優(yōu)先級 .setPriority(priority) //是否提示一次.true - 如果Notification已經(jīng)存在狀態(tài)欄即使在調(diào)用notify函數(shù)也不會更新 .setOnlyAlertOnce(onlyAlertOnce) .setAutoCancel(true); if (remoteViews!=null){ //設(shè)置自定義view通知欄 notificationBuilder.setContent(remoteViews); } if (intent!=null){ notificationBuilder.setContentIntent(intent); } if (ticker!=null && ticker.length()>0){ //設(shè)置狀態(tài)欄的標(biāo)題 notificationBuilder.setTicker(ticker); } if (when!=0){ //設(shè)置通知時間,默認(rèn)為系統(tǒng)發(fā)出通知的時間,通常不用設(shè)置 notificationBuilder.setWhen(when); } if (sound!=null){ //設(shè)置sound notificationBuilder.setSound(sound); } if (defaults!=0){ //設(shè)置默認(rèn)的提示音 notificationBuilder.setDefaults(defaults); } if (pattern!=null){ //自定義震動效果 notificationBuilder.setVibrate(pattern); } return notificationBuilder; } private boolean ongoing = false; private RemoteViews remoteViews = null; private PendingIntent intent = null; private String ticker = ""; private int priority = Notification.PRIORITY_DEFAULT; private boolean onlyAlertOnce = false; private long when = 0; private Uri sound = null; private int defaults = 0; private long[] pattern = null; /** * 讓通知左右滑的時候是否可以取消通知 * @param ongoing 是否可以取消通知 * @return */ public NotificationUtils setOngoing(boolean ongoing){ this.ongoing = ongoing; return this; } /** * 設(shè)置自定義view通知欄布局 * @param remoteViews view * @return */ public NotificationUtils setContent(RemoteViews remoteViews){ this.remoteViews = remoteViews; return this; } /** * 設(shè)置內(nèi)容點擊 * @param intent intent * @return */ public NotificationUtils setContentIntent(PendingIntent intent){ this.intent = intent; return this; } /** * 設(shè)置狀態(tài)欄的標(biāo)題 * @param ticker 狀態(tài)欄的標(biāo)題 * @return */ public NotificationUtils setTicker(String ticker){ this.ticker = ticker; return this; } /** * 設(shè)置優(yōu)先級 * 注意: * Android 8.0以及上,在 NotificationChannel 的構(gòu)造函數(shù)中指定,總共要五個級別; * Android 7.1(API 25)及以下的設(shè)備,還得調(diào)用NotificationCompat 的 setPriority方法來設(shè)置 * * @param priority 優(yōu)先級,默認(rèn)是Notification.PRIORITY_DEFAULT * @return */ public NotificationUtils setPriority(int priority){ this.priority = priority; return this; } /** * 是否提示一次.true - 如果Notification已經(jīng)存在狀態(tài)欄即使在調(diào)用notify函數(shù)也不會更新 * @param onlyAlertOnce 是否只提示一次,默認(rèn)是false * @return */ public NotificationUtils setOnlyAlertOnce(boolean onlyAlertOnce){ this.onlyAlertOnce = onlyAlertOnce; return this; } /** * 設(shè)置通知時間,默認(rèn)為系統(tǒng)發(fā)出通知的時間,通常不用設(shè)置 * @param when when * @return */ public NotificationUtils setWhen(long when){ this.when = when; return this; } /** * 設(shè)置sound * @param sound sound * @return */ public NotificationUtils setSound(Uri sound){ this.sound = sound; return this; } /** * 設(shè)置默認(rèn)的提示音 * @param defaults defaults * @return */ public NotificationUtils setDefaults(int defaults){ this.defaults = defaults; return this; } /** * 自定義震動效果 * @param pattern pattern * @return */ public NotificationUtils setVibrate(long[] pattern){ this.pattern = pattern; return this; } /** * 設(shè)置flag標(biāo)簽 * @param flags flags * @return */ public NotificationUtils setFlags(int... flags){ this.flags = flags; return this; } } ```
1.技術(shù)博客匯總
2.開源項目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客我的個人站點:www.yczbj.org,www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
開源中國:https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72307.html
摘要:是新增的,用于向用戶配置和顯示桌面通知。通知不自動關(guān)閉,默認(rèn)為自動關(guān)閉。在瀏覽器下,沒有關(guān)閉請求權(quán)限的選項,用戶必須選擇同意拒絕。 showImg(https://segmentfault.com/img/remote/1460000018227718); Notification是HTML5新增的API,用于向用戶配置和顯示桌面通知。上次在別的網(wǎng)站上看到別人的通知彈窗,好奇之余也想知...
摘要:簡介通知在用戶界面的一個重要部分,其使用方法請看以下內(nèi)容繼承關(guān)系如下簡介通知是應(yīng)用向用戶顯示的消息提示,當(dāng)發(fā)送通知時,通知將先以圖標(biāo)的形式顯示在通知區(qū)域中。通知區(qū)域和下拉通知欄均是由系統(tǒng)控制的區(qū)域,用戶可以隨時查看。 showImg(https://segmentfault.com/img/remote/1460000019975019?w=157&h=54); 極力推薦文章:歡迎收藏...
摘要:據(jù)猜測是為瀏覽器翻譯服務(wù)。通知內(nèi)容,顯示在通知標(biāo)題之下,默認(rèn)為空字符串標(biāo)記通知的類型,打上標(biāo)簽,默認(rèn)為空字符串。在最新的技術(shù)評審稿中,該參數(shù)被舍棄設(shè)置該標(biāo)志表示最終用戶將不能很容易地清除。設(shè)置該標(biāo)志,通知將為永久型通知。 Web Notification 網(wǎng)頁通知API。這是2011年由谷歌技術(shù)員John Gregg提出的一項網(wǎng)頁通知api。 定義 請讀者直接參考whatwg工作組對...
閱讀 1957·2021-11-15 17:58
閱讀 2136·2021-10-19 11:45
閱讀 3502·2021-09-02 15:40
閱讀 2604·2021-07-25 10:50
閱讀 3752·2019-08-30 15:56
閱讀 3153·2019-08-30 12:44
閱讀 1036·2019-08-26 13:38
閱讀 1878·2019-08-23 18:29