Reputation: 321
I'm new to android development and Java, and I'm slightly confused about the handling of backwards compatibility when using classes that have been introduced in the latest versions.
I've checked out the android support library and see the various XXXCompat
classes available. For the ones I've looked at they appear to pretty much branch on VERSION.SDK_INT
and call a new api or an old api.
I am using a support library (com.android.support:support-v4:27.1.1
) version that is targeted for a newer api than my targetSdkVersion (25
). I was under the impression this was the intended use case? to be able to write code with newer api's but have it work when targeting older sdk.
If so, how is this possible? For instance ContextCompat
is has the following for startForegroundService
public static void startForegroundService(@NonNull Context context,
@NonNull Intent intent) {
if (VERSION.SDK_INT >= 26) {
context.startForegroundService(intent);
} else {
context.startService(intent);
}
}
However in the version I am targeting the Context doesn't have the method startForegroundService
. If paste this if block into my code, it fails to compile with java: cannot find symbol ...
.
I can only assume that even if you compiled against a newer api (such that it could resolve the symbols), if those symbols don't exist at runtime, as long a they are not called it is not a problem?
So this is fine for api calls that are abstracted by the XXXCompat
classes, but when using new classes like NotificationChannel
. I can only import this if upping my targetSdkVersion
to > 26. So assuming I do this, then this class is available. All uses of it that I have seen do
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
NotificationChannel channel = ...
}
Does this mean that at runtime, for lower Build.VERSION.SDK_INT
the symbol NotificationChannel
will not exist? and if I attempted to instantiate this class it on a lower android version, it would crash?
Upvotes: 2
Views: 1299
Reputation: 624
Before Oreo, you can just start your service. For Oreo and higher, the service needs to run in foreground and thus post a notification upon service start otherwise it gets destroyed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
To post notification in Oreo and above you need to create a notification channel, before Oreo you just add your channel id to the notification builder (no need to create a channel). Snippet code from service:
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)
When you create createNotificationChannel
function, just annotate it with @RequiresApi(26)
.
Upvotes: 2