1. 程式人生 > >Android 通知相關適配及總結

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的設定頁面有沒有開啟“後臺彈出介面”開關)。