Android NotificationChannel与旧版API的兼容性

时间:2019-01-27 16:58:52

标签: java android android-notifications

我是android开发和Java的新手,在使用最新版本中引入的类时,我对处理向后兼容性感到有些困惑。

我已经签出了android支持库,并查看了各种XXXCompat类。对于我看过的那些对象,它们似乎在VERSION.SDK_INT上有很多分支,并调用新的api或旧的api。

我使用的支持库(com.android.support:support-v4:27.1.1)版本的目标是比我的targetSdkVersion(25)更高的api。我的印象是这是预期的用例?能够使用较新的api编写代码,但在定位较旧的sdk时可以正常工作。

如果是这样,这怎么可能?例如ContextCompat具有startForegroundService

的以下内容
public static void startForegroundService(@NonNull Context context, 
@NonNull Intent intent) {
    if (VERSION.SDK_INT >= 26) {
        context.startForegroundService(intent);
    } else {
        context.startService(intent);
    }
}

但是,在我定位到Context的版本中,没有方法startForegroundService。如果将此if块粘贴到我的代码中,则无法使用java: cannot find symbol ...进行编译。

我只能假设即使您是根据较新的api编译的(这样它就可以解析符号),如果这些符号在运行时不存在,只要不被调用,这不是问题吗? / p>

因此,这对于由XXXCompat类抽象的api调用来说很好,但是在使用诸如NotificationChannel这样的新类时。如果将我的targetSdkVersion提升到> 26,则只能导入该类。因此,假设执行此操作,则该类可用。我见过的所有用法

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
   NotificationChannel channel = ...
}

这是否意味着在运行时,对于较低的Build.VERSION.SDK_INT,符号NotificationChannel将不存在?如果我尝试在较低的android版本上实例化此类,它将崩溃?

1 个答案:

答案 0 :(得分:0)

在奥利奥之前,您只需启动服务即可。对于Oreo及更高版本,该服务需要在前台运行,并因此在服务启动时发布通知,否则它将被销毁。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent)
} else {
    startService(intent)
}

要在Oreo及更高版本中发布通知,您需要创建一个通知频道,在Oreo之前,您只需将您的频道ID添加到通知生成器(无需创建频道)即可。服务中的代码段:

String channelId = "myAppChannel"

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // build notification channel
    createNotificationChannel(channelId, ...)
}

NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, channelId)

// Build your notification
Notification notification = notificationBuilder
        .setOngoing(true)
        .setSmallIcon(icon)
        .setCategory(Notification.CATEGORY_SERVICE)
        .build()

// post notification belonging to this service
startForeground(NOTIFICATION_ID, notification)

创建createNotificationChannel函数时,只需用@RequiresApi(26)对其进行注释。