前些天性致脖脖地點進入了developer.android.com亏掀,想看下通知這塊內容忱反,你懂的。首先映入眼簾的就是下面這玩意兒滤愕,翻譯速度闊以哦N滤恪!间影!
通知渠道米者?啥玩意兒,啊宇智,走過路過,千萬不要錯過啊胰丁,點進去瞧瞧唄随橘。看到代碼锦庸,必須先敲完運行下啊机蔗。什么情況,Api 26上根本就出不來什么通知啊甘萧。
心想谷歌還是嚴謹的萝嘁,就選擇相信了它。于是我打開了英文版扬卷。
通知渠道
先看什么是通知渠道牙言。來看下官方解釋:
Notification channels: Android 8.0 introduces notification channels that allow you to create a user-customizable channel for each type of notification you want to display.
啥意思?就是說這個面包我不想一個一個做了怪得,做一個模子咱枉,把面粉放進去,就行了徒恋,形象吧蚕断。
沒錯,這些就是通知渠道入挣。
我們可以看出亿乳,每個通知渠道都有一個名稱,進去之后還有很多其他屬性径筏,如重要程序葛假、通知圓點障陶、閃爍燈等等。喂喂桐款,那位拿8.0以下的手機試的同學咸这,給我出去!
那有的同學要問了魔眨,怎樣才能在App中顯示一個通知渠道呢媳维。問得好,我們直接上代碼遏暴。
/**
* Oreo不用Priority了侄刽,用importance
* IMPORTANCE_NONE 關閉通知
* IMPORTANCE_MIN 開啟通知,不會彈出朋凉,但沒有提示音州丹,狀態(tài)欄中無顯示
* IMPORTANCE_LOW 開啟通知,不會彈出杂彭,不發(fā)出提示音墓毒,狀態(tài)欄中顯示
* IMPORTANCE_DEFAULT 開啟通知,不會彈出亲怠,發(fā)出提示音所计,狀態(tài)欄中顯示
* IMPORTANCE_HIGH 開啟通知,會彈出团秽,發(fā)出提示音主胧,狀態(tài)欄中顯示
*/
val channel = NotificationChannel("渠道ID",
"測試渠道名稱",
NotificationManager.IMPORTANCE_HIGH)
// 獲取NotificationManager
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
// 創(chuàng)建通知渠道
notificationManager.createNotificationChannel(channel)
就這么簡單,對习勤,就是這么簡單暴力踪栋!
那如果想修改渠道屬性怎么辦呢?還是上面的代碼图毕,不過……
敲黑板夷都,畫重點,注意聽了啊予颤,只講一遍损肛,目前只有名稱和描述可以直接改,其他的要看到修改后的結果只能先對App執(zhí)行清除數據操作荣瑟,那么問題來了治拿,渠道還有哪些屬性呢,我們不防點進去看看笆焰。
我們結合代碼來看下劫谅。
// 設置提示音,IMPORTANCE_DEFAULT及以上才會有聲音
channel.setSound(Uri.parse("..//aa.mp3"), AudioAttributes.Builder().build())
// 震動設置
channel.enableVibration(true)
// 設置震動模式,不設置使用系統(tǒng)默認
channel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
// 閃爍指示燈設置
channel.enableLights(true)
// 指示燈顏色設置(不是每一個手機都支持哦)
channel.lightColor = Color.RED
// 屏幕鎖定時通知顯示方式(無法更改)
channel.lockscreenVisibility = Notification.VISIBILITY_SECRET
// 覆蓋勿擾設置(無法更改)
channel.setBypassDnd(true)
// 獲取NotificationManager
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// 通知描述
channel.description = "測試通知描述"
// 創(chuàng)建通知渠道
notificationManager.createNotificationChannel(channel)
其中“l(fā)ockscreenVisibility”和“setBypassDnd”是無法生效的捏检,因為從源碼中來看荞驴,
只能被系統(tǒng)或排序服務(Android Notification Ranking Service)更改。
那么通知怎么跟通知渠道關聯呢贯城?Api26以上熊楼,創(chuàng)建通知需要提供渠道ID。
// 根據渠道創(chuàng)建通知
val notificationBuilder = Notification.Builder(this@TestActivity,
"渠道ID")
.setSmallIcon(R.drawable.ic_notification_logo)
.setContentTitle("測試通知標題")
.setContentText("測試通知內容")
// 彈出通知
notificationManager.notify(1, notificationBuilder.build())
接下來我們看看如果給渠道分組能犯。渠道組對象是NotificationChannelGroup鲫骗,也有一個ID和一個名稱,創(chuàng)建一個渠道組很簡單:
// 創(chuàng)建一個渠道組
val channelGroup = NotificationChannelGroup("測試組ID", "渠道組名")
// 綁定渠道組
channel.group = "測試組ID"
notificationManager.createNotificationChannelGroup(channelGroup)
上面代碼創(chuàng)建渠道組和完成渠道與渠道組的綁定踩晶,如果渠道有綁定渠道組执泰,必須先創(chuàng)建渠道組,再創(chuàng)建渠道哦渡蜻。
關于渠道和渠道組的查詢刪除术吝,就不用多說了吧。
// 查詢所有當前用戶的所有渠道
notificationManager.notificationChannelGroups
// 查詢所有當前用戶的所有渠道組
notificationManager.notificationChannels
// 根據ID刪除渠道
notificationManager.deleteNotificationChannel("渠道ID")
// 根據ID刪除渠道組
notificationManager.deleteNotificationChannel("測試組ID")
下面幾個特性倒簡單茸苇,我就稍微說說了排苍。
通知角標
通知圓點可以在創(chuàng)建渠道時指定,要是創(chuàng)建時沒指定修改時指定記得給App清除數據哦学密。
// 顯示通知圓點
channel.setShowBadge(true)
打盹兒
自動消失
val notificationBuilder = Notification.Builder(this@TestActivity,
.setTimeoutAfter(5000L)
都很正常纪岁,然而坑往往就。则果。。
setSettingText
大概意思還是能猜到的漩氨,就是說8.0你可以通過INTENT_CATEGORY_NOTIFICATION_PREFERENCES
給通知加一個入口到你應用的通知設置里西壮,而且還可以用setSettingsText()給入口指定文字。給個頁面或demo會死啊叫惊,通知那一章節(jié)也只字不提這玩意兒了款青。再進setSettingText():
什么是affordance,難道不是下面這個齒輪嘛霍狰,難不成下面"MORE SETTINGS"這塊文字能改抡草?還是too young啊蔗坯!
無奈只好谷歌唄康震。
我竟然寄希望去百度了。
看到第一條喜出望外氨霰簟腿短!誰知道特么是官方文檔的翻譯,多的圖就不截了,誰搜誰知道橘忱「翱可不能就這樣放棄啊,今早從overflow上搜到了唯一一個钝诚,不過是自己昨晚提的颖御。
試著從INTENT_CATEGORY_NOTIFICATION_PREFERENCES突破,總算有一點點進步凝颇。
<activity android:name=".AppNotificationSettingsActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.
NOTIFICATION_PREFERENCES"/>
</intent-filter>
</activity>
本以為setSettingText() 可以改變上面文字潘拱,又一次失望了,昨晚看了youtube上的幾個片子祈噪,均無介紹泽铛。就連兼容類NotificationCompat.Builder中都無setSettingText()方法。好吧辑鲤,我決定看了源碼之后再告訴你們盔腔,放我一條生路先!
再來看第二坑
傻乎乎地敲完了月褥,試著移除幾個通知弛随,毛線都沒有啊。
class NLService : NotificationListenerService(){
override fun onNotificationPosted(sbn: StatusBarNotification?) {
super.onNotificationPosted(sbn)
if(packageName == sbn?.packageName)
Log.i(TAG, "onNotificationPosted" + sbn.toString())
}
override fun onNotificationRemoved(sbn: StatusBarNotification?) {
super.onNotificationRemoved(sbn)
if(packageName == sbn?.packageName)
Log.i(TAG, "onNotificationRemoved" + sbn.toString())
}
<service
android:name=".NLService"
android:label="@string/nlservice_name"
android:permission="android.permission.BIND_NOTIFICATION_
LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.
NotificationListenerService"/>
</intent-filter>
</service>
原來是要手動開啟通知訪問權限啊宁赤。以Pixel為例舀透,設置>應用和通知>高級>特殊應用權限->通知使用權。
還有坑决左?
看樣子是能改背景色愕够?好吧。
這是背景色嗎佛猛?這是背景色嗎惑芭?
機智如我,看到這下面這句話继找。
于是代碼就成這樣嘍遂跟。
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = intent?.getParcelableExtra<Notification>(ARG_NOTIFICATION)
if(notification != null){
startForeground(1, notification)
mHandler?.postDelayed(Runnable {
stopForeground(true)
}, TestNotificationColorService.DURATION_NOTIFICATION_DISMISS)
}
return super.onStartCommand(intent, flags, startId)
}
終于硬了一把。
最后一個終于不是坑了婴渡,大家放心踩幻锁,出了問題找我。
// If Showing message style notification, create some test data.
val showMessageStyleView = view?.findViewById<CheckBox>(R.id.message_style_ck)
if(showMessageStyleView != null && showMessageStyleView.isChecked){
builder.setStyle(NotificationCompat.MessagingStyle(getString(R.string.test_display_name))
.setConversationTitle(getString(R.string.test_conversation_title))
.addMessage(getString(R.string.test_message_chat1), System.currentTimeMillis(), getString(R.string.test_sender))
.addMessage(getString(R.string.test_message_chat2), System.currentTimeMillis(), getString(R.string.test_sender)))
}
以上demo已上傳至:https://github.com/andrsay/OreoNotificationSample