概覽
通知是 android 系統存在至今為止被變更最為頻繁的 api 之一,android 4.1、4.4、5.0、7.0、8.0 都對通知做過比較大的改動,到了 8.0 通知功能趨于穩定,至今沒有做過更大的改動,
對一個 api 進行如此大的照顧那么這必然是個非常重要的 api 了,那么就跟隨我一起揭開通知一點都不神秘的面紗吧,
注:本文主要講應用
通知使用
創建簡單通知
我們使用 NotificationCompat 來創建通知,使用 NotificationCompat 可以兼容所有的系統版本,不需要我們去手動兼容版本,
創建通知分為兩個步驟:
- 創建渠道
- 創建通知
關于渠道
創建渠道
notificationManager.createNotificationChannel(channel)
安卓 8.0 系統要求必須創建渠道才能展示通知,所以我們在 8.0 的系統版本中,必須添加創建渠道的方法,
創建渠道不一定非要在展示通知的時候做,同一個渠道只需要被創建一次即可(多次亦可),我們可以在我們即將展示通知的時候創建,可以再應用啟動的時候創建,也可以在 activity 中創建,總之渠道創建非常靈活
如果渠道已經存在我們仍然呼叫了創建渠道方法,那么什么也不會做,很安全
下面代碼是我們創建渠道的完整代碼:
private val channelName = "安安安安卓"
private val channelId = "channelId"
fun createNotificationChannel(context: Context): NotificationChannel? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val descriptionText = "渠道描述"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, channelName, importance).apply {
description = descriptionText
}
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
return channel
}
return null
}
渠道重要性設定
需要注意,渠道的優先級和通知的優先級是不同的,注意區分
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(channelId, channelName, importance)
上面的代碼創建了通知的重要程度,我們需要說明一下 NotificationChannel 的第三個引數,也就是渠道的重要程度,這個設定不同的值,用戶收到通知后手機的展示包括聲音、震動、是否彈出都會不同,下面看一下引數的四種設定(四個引數在不同手機的渠道展示不同):
- IMPORTANCE_HIGH 收到通知發出提示語,并且會浮動提示用戶(小米手機表示緊急)
- IMPORTANCE_DEFAULT 收到通知發出提示語,不會浮動提示(小米手機表示高)
- IMPORTANCE_LOW 收到通知不會發出聲音,狀態欄有小圖示展示(小米手機表示中)
- IMPORTANCE_MIN 根本看不到通知(所以你壓根就別用就 ok 了),不過似乎可以用于禁用通知的場景(小米手機表示低)
禁用某個渠道的通知方法
我們使用創建渠道的方式實作禁用通知,如下:
比如我們第一次創建渠道的時候代碼如下:
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(channelId, channelName, importance)
這行代碼會創建一個有聲音提示、橫幅展示(google 檔案管這個叫偷窺模式 😄)的渠道,
如果此時用戶通過我們 app 內部的設定想不在收到我們這個渠道的通知,我們需要如下代碼這樣做:
val importance = NotificationManager.IMPORTANCE_MIN
val channel = NotificationChannel(channelId, channelName, importance)
與上一處的代碼的區別是把 IMPORTANCE_HIGH 改成了 IMPORTANCE_MIN,因此我們的渠道就變成了 低級別通知渠道,收到通知也無法展示,因此用戶根本看不到通知,從而實作了通知禁用,
還有一點需要注意,我們可以通過代碼將一個高優先級的渠道設定為低優先級渠道,但是無法將低優先級渠道設定為高優先級渠道,
關于通知
創建通知
通知大家都太熟悉,直接上代碼,記得看注釋
private val channelName = "安安安安卓"
private val channelId = "channelId"
fun showNotification(context: Context) {
val notification = NotificationCompat.Builder(context, channelName)//這里的渠道名就是你自己想展示通知對應的渠道分組
.setSmallIcon(R.drawable.apple)//設定狀態欄展示的通知樣式
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))//設定通知中的圖示樣式
.setContentTitle("公眾號")//設定通知標題
.setContentText("安安安安卓")//設定通知正文
.setChannelId(channelId)//設定通知渠道,這個渠道id必須是和我們創建渠道時候的id對應
.setPriority(NotificationCompat.PRIORITY_DEFAULT).build()//設定通知優先級
NotificationManagerCompat.from(context).notify(13, notification)
}
強調一下:展示通知之前一定要先創建渠道
通知中的優先級
設定方法:NotificationCompat.Builder.setPriority
通知優先級極容易跟渠道優先級混淆,一定要注意區分
通知優先級有以下幾種:
- PRIORITY_DEFAULT = 0;默認優先級
- PRIORITY_LOW = -1; 低優先級
- PRIORITY_MIN = -2;最低優先級
- PRIORITY_HIGH = 1;高優先級
- PRIORITY_MAX = 2;最高優先級
這個引數主要是給我們的通知進行排序,重要的通知放在前面展示,這可以幫助我們第一時間找到最重要的通知進行處理,這很實用不是嗎?
展示效果
模擬器的展示效果:


創建展開式通知
創建代碼
我們可以再創建 NotificationCompat.Builder 的時候加上如下呼叫就可以展示展開式通知:
.setStyle(
NotificationCompat.BigTextStyle()
.bigText("本文由 公眾號 \"安安安安卓\"作者原創,禁抄襲\n 北國風光," +
"千里冰封,萬里雪飄,望長城內外,惟余莽莽,大河上下,頓失滔滔,山舞銀蛇,原馳蠟象,欲與天公試比高," +
"須晴日,看銀裝素裹,分外妖嬈")
)
通知默認是展開式的,長按通知可以在短文本和長文本之間來回切換
展示效果

設定通知的點擊事件
如下代碼實作一個可點擊的通知欄
fun showNotification(context: Context) {
val intent = Intent(context,OnlyShowActivity::class.java).apply {
flags=Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent=PendingIntent.getActivity(context,0,intent,0)
val notification = NotificationCompat.Builder(context, channelId)
.setContentText("點擊通知跳轉的一個頁面中")
.setContentTitle("可點擊通知")
.setSmallIcon(R.drawable.apple)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))
.setAutoCancel(true)//設定點擊了通知,則通知自動消失
.setContentIntent(pendingIntent)
.build()
NotificationManagerCompat.from(context).notify(++count, notification)
}
給通知欄設定按鈕
我們可以通過 addAction 給通知設定 action,同時可以指定一個 PendingIntent,
fun showBtnNotification(context: Context) {
val intent = Intent(context, OnlyShowActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
val notification = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.apple)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.apple))
.setContentText("安安安安卓,北國風光,千里冰封,萬里雪飄")
.setContentTitle("按鈕通知")
.addAction(R.drawable.person, "李白", pendingIntent)
.addAction(R.drawable.apple, "杜甫", pendingIntent)
.addAction(R.drawable.apple, "王維", pendingIntent)
.setAutoCancel(true)
.build()
NotificationManagerCompat.from(context).notify(++count, notification)
}
設定進度條
private val countdown = object : CountDownTimer(15 * 1000, 1000) {
private val perdegree = 100 / 15
var count = 0
override fun onTick(millisUntilFinished: Long) {
count++
showNotification(count * perdegree)//更新進度
}
override fun onFinish() {
showNotification(100)
count = 0
}
}
/**
* 啟動一個可動的進度條
*/
fun start() {
countdown.start()
}
private fun showNotification(progress: Int) {
val builder = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.apple)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.person))
.setColor(Color.GREEN)
.setContentTitle("這是個進度標題")
NotificationManagerCompat.from(context).apply {
builder.setProgress(100, progress, false)
builder.setContentText("下載進度 $progress%")
notify(count, builder.build())
}
}
效果圖:

設定自定義通知
我們可以通過 RemoteViews 指定一個布局,通過 setCustomContentView 設定我們的自定義布局
代碼:
fun showNotification(context: Context){
val remoteViews = RemoteViews(context.packageName, R.layout.item_notification)
val notification = NotificationCompat.Builder(context, channelId)
.setContentTitle("這個通知的布局是自定義的")
.setContentText("安安安安卓")
.setSmallIcon(R.drawable.apple)
.setLargeIcon(BitmapFactory.decodeResource(context.resources, R.drawable.person))
.setCustomContentView(remoteViews)
.build()
NotificationManagerCompat.from(context).notify(count,notification)
}
我們的 xml 代碼預覽圖:

最終效果圖:

其它的知識點
- 從 android8.1 開始,應用一秒鐘最多只能發出一次通知提示音,如果出現多條通知只有一條通知可以出發提示音
- 創建通知的幾種樣式:NotificationCompat.BigPictureStyle、NotificationCompat.BigTextStyle、NotificationCompat.DecoratedCustomViewStyle
- NotificationCompat.Builder.setGroup 方法可以創建一組通知
- NotificationManager.getNotificationChannel()或 NotificationManager.getNotificationChannels()兩個方法可以獲取通知的渠道,通過獲取到的渠道可以獲取此渠道是否開啟聲音、渠道通知的重要級別,我們可以據此提示用戶打開相應的設定,下面代碼展示了打開通知渠道的方法:
Intent intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
intent.putExtra(Settings.EXTRA_CHANNEL_ID, myNotificationChannel.getId());
startActivity(intent);
- 洗掉渠道的方法 deleteNotificationChannel()
- 我們可以呼叫渠道的 NotificationChannel.setShowBadge(false)方法關閉桌面圖示圓點,這個其實很有用,比如當你用通知展示下載進度條的時候這條通知明顯是不需要展示圓點的,還有大部分的本地提醒類通知都不會希望顯示圓點的,用這個方法正好
- NotificationCompat.Builder.setNumber 方法可以設定桌面圖示的紅點數量
- 通過 NotificationCompat.DecoratedCustomViewStyle 樣式可以給內容區域創建自定義布局,樣式就是通知展示圖示在左,我們自定義的布局在右,不過這個感覺就沒啥用了,
- 自定義布局的通知也可以給內部的 view 添加點擊跳轉事件,實作方法如下代碼:
val remoteViews = RemoteViews(context.packageName, R.layout.item_notification)
val intent = Intent(context,OnlyShowActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context,0,intent,0)
remoteViews.setOnClickPendingIntent(R.id.iv_pendingintent_click,pendingIntent)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/294504.html
標籤:其他
上一篇:[ROC-RK3568-PC] 使用adb push檔案到Android 11列印Read-only file system的解決方法
