Android 通知相關適配及總結
一、高版本適配之渠道
targetVersion為Android 8.0及以上的版本,需要建立通知的渠道(channel),否則就不會顯示通知。(注:渠道的建立不會影響低版本,低版本會忽略渠道)
private fun createNotificationChannel() { // Create the NotificationChannel, but only on API 26+ because // the NotificationChannel class is new and not in the support library if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = getString(R.string.channel_name) val descriptionText = getString(R.string.channel_description) val importance = NotificationManager.IMPORTANCE_DEFAULT val channel = NotificationChannel(CHANNEL_ID, name, importance).apply { description = descriptionText } // Register the channel with the system val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } }
在每次傳送通知之前及在應用的Application的onCreate方法中呼叫上述方法。
有些同學可能會疑惑,每次都發通知都重新建立一次,會不會產生問題?
不會。官方文件裡面已經明確的告訴了我們:creating an existing notification channel performs no operation。當然,你也可以宣告一個boolean值,用於控制當已建立渠道,不再執行上述建立程式碼。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !isCreateApkDownloadChannel){ ...... }
當然僅僅是呼叫上述方法還是不行的,通知的建立程式碼也需要修改一下:
val mBuilder = NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Set the intent that will fire when the user taps the notification .setContentIntent(pendingIntent) .setAutoCancel(true)
可以看到,通知的建立主要變化的點是需要多傳入一個ChannelId,這個ChannelId的值需要和建立渠道時傳入的值保持一直,這樣相同channelId的通知才會被歸為一類。
效果(以頭條App為例):
二、優先順序適配
優先順序的適配包含了高版本(8.0及以上)和低版本(7.0及以下),每個通知都有不同的優先順序,優先順序的高低與聲音及展示方式密切相關。如下圖:
為了適配全版本,我們必須為8.0及以上 && 7.0及以下,各自設定優先順序。上述建立channel及notification的程式碼已經包含了如何設定各自優先順序的地方了,此處就不再重複貼程式碼。即:渠道中的優先順序 - 針對8.0及以上,建立通知 - setPriority - 針對的是7.0及以下版本。
具體設定成什麼優先順序取決於自己的業務需求。比如:普通通知和下載Apk進度通知。這兩個通知的優先順序肯定不能一樣,因為你肯定不想自己的使用者在下載Apk的時候,一直髮出滴滴滴滴的聲音,那樣使用者可能會手滑解除安裝你的App了。因此,可以為不同的型別的通知建立不同的渠道,進而設定不同的優先順序。
三、特殊機型收不到通知?
比如vivo x20手機,預設情況下,新安裝的App的“允許通知”選項被關閉了。這時候你的app傳送的任何通知,使用者手機都是收不到的。由於系統提供了相關的api可以檢測到是否開啟,因此做法還是比較簡單的,檢測&提示給使用者即可。
public static boolean areNotificationsEnabled(Context context) {
return context == null || NotificationManagerCompat.from(context).areNotificationsEnabled();
}
如果上述函式返回false,提示使用者開啟,並在使用者點選設定時跳轉到app設定頁面。
四、點選通知,無法調起後臺App?
這個也是vivo手機的一個坑。如果你的app處於後臺,且此時你需要如標題所述的場景,那麼是無法調起的。為什麼?vivo也是預設禁止了app“後臺彈出介面”。目前,我還沒發現相關的系統的api可以解決這個問題。麻煩看到的同學,知道的留言一下。如下是我們的解決方案:
雖然被禁止了“後臺彈出介面”,但是還是會走調起activity的程式碼(launchApp),只是走完程式碼沒任何毛效果而已。可以在這段調起的程式碼中設定一個計時器 && 一個布林值(布林值本地SP快取一下),當指定的時間內成功跳轉至調起頁,則設定布林值為true。如果指定的時間內,布林值仍然為false,則說明使用者手機禁止了“後臺彈出介面”。
在使用者下一次開啟App的時候,提示使用者。(目前只提示一次,因為不知道使用者在app的設定頁面有沒有開啟“後臺彈出介面”開關)。