Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Testable Kotlin Android OS version checker, with tests

How to use the checker

Java

import static me.seebrock3r.utils.VersionChecker.android;

if (android().isLollipopOrLater()) {
  // ...
}

// OR

switch (android().sdkVersion()) {
  case Build.SDK_INT.O:
    //...
    break;
  case Build.SDK_INT.LOLLIPOP:
    //...
    break;
  default:
    //...
    break;
}

Kotlin

import me.seebrock3r.utils.android 

if (android.isLollipopOrLater()) {
  // ...
}

// OR

when (android.sdkVersion) {
  Build.SDK_INT.O -> //...
  Build.SDK_INT.LOLLIPOP -> //...
  else -> //...
}
package me.seebrock3r.utils
import android.os.Build.VERSION_CODES.JELLY_BEAN_MR1
import android.os.Build.VERSION_CODES.JELLY_BEAN_MR2
import android.os.Build.VERSION_CODES.KITKAT
import android.os.Build.VERSION_CODES.LOLLIPOP
import android.os.Build.VERSION_CODES.LOLLIPOP_MR1
import android.os.Build.VERSION_CODES.M
import android.os.Build.VERSION_CODES.N
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
// Notes: these are JVM Junit 4.12 tests. The assertions require AssertJ, or Truth. Pick your poison, just tweak the imports.
@RunWith(Parameterized::class)
class AndroidOSVersionCheckerTest(private val checker: OSVersionChecker, private val currentSdkVersion: Int) {
companion object {
@Parameterized.Parameters(name = "{index}: SDK_INT {1}")
@JvmStatic
fun data(): Collection<Array<Any>> {
return listOf(
arrayOf(AndroidOSVersionChecker(JELLY_BEAN_MR1), JELLY_BEAN_MR1),
arrayOf(AndroidOSVersionChecker(JELLY_BEAN_MR2), JELLY_BEAN_MR2),
arrayOf(AndroidOSVersionChecker(KITKAT), KITKAT),
arrayOf(AndroidOSVersionChecker(LOLLIPOP), LOLLIPOP),
arrayOf(AndroidOSVersionChecker(LOLLIPOP_MR1), LOLLIPOP_MR1),
arrayOf(AndroidOSVersionChecker(M), M),
arrayOf(AndroidOSVersionChecker(N), N),
arrayOf(AndroidOSVersionChecker(N_MR1), N_MR1),
arrayOf(AndroidOSVersionChecker(O), O)
)
}
}
@Test
fun `should report correct SDK version`() {
assertThat(checker.sdkVersion).isEqualTo(currentSdkVersion)
}
@Test
fun `should detect correctly if Oreo or later`() {
assertThat(checker.isAtLeastOreo).isEqualTo(currentSdkVersion >= O)
}
@Test
fun `should detect correctly if NougatMR1 or later`() {
assertThat(checker.isAtLeastNougatMR1).isEqualTo(currentSdkVersion >= N_MR1)
}
@Test
fun `should detect correctly if Nougat or later`() {
assertThat(checker.isAtLeastNougat).isEqualTo(currentSdkVersion >= N)
}
@Test
fun `should detect correctly if Marshmallow or later`() {
assertThat(checker.isAtLeastMarshmallow).isEqualTo(currentSdkVersion >= M)
}
@Test
fun `should detect correctly if LollipopMR1 or later`() {
assertThat(checker.isAtLeastLollipopMR1).isEqualTo(currentSdkVersion >= LOLLIPOP_MR1)
}
@Test
fun `should detect correctly if Lollipop or later`() {
assertThat(checker.isAtLeastLollipop).isEqualTo(currentSdkVersion >= LOLLIPOP)
}
@Test
fun `should detect correctly if KitKat or later`() {
assertThat(checker.isAtLeastKitKat).isEqualTo(currentSdkVersion >= KITKAT)
}
@Test
fun `should detect correctly if JellyBeanMR2 or later`() {
assertThat(checker.isAtLeastJellyBeanMR2).isEqualTo(currentSdkVersion >= JELLY_BEAN_MR2)
}
@Test
fun `should detect correctly if JellyBeanMR1 or later`() {
assertThat(checker.isAtLeastJellyBeanMR1).isEqualTo(currentSdkVersion >= JELLY_BEAN_MR1)
}
}
@file:JvmName("VersionChecker")
package me.seebrock3r.utils
import android.annotation.SuppressLint
import android.os.Build
import android.support.annotation.VisibleForTesting
val android: OSVersionChecker
@SuppressLint("VisibleForTests") // Accessing it as private would be correct here, probably a Lint bug with Kotlin visibilities
@JvmName("android")
get() = AndroidOSVersionChecker()
interface OSVersionChecker {
val sdkVersion: Int
val isAtLeastOreo: Boolean
val isAtLeastNougatMR1: Boolean
val isAtLeastNougat: Boolean
val isAtLeastMarshmallow: Boolean
val isAtLeastLollipop: Boolean
val isAtLeastLollipopMR1: Boolean
val isAtLeastKitKat: Boolean
val isAtLeastJellyBeanMR2: Boolean
val isAtLeastJellyBeanMR1: Boolean
}
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal class AndroidOSVersionChecker(sdkVersionInt: Int = Build.VERSION.SDK_INT) : OSVersionChecker {
override val sdkVersion = sdkVersionInt
override val isAtLeastOreo = sdkVersionInt >= Build.VERSION_CODES.O
override val isAtLeastNougatMR1 = sdkVersionInt >= Build.VERSION_CODES.N_MR1
override val isAtLeastNougat = sdkVersionInt >= Build.VERSION_CODES.N
override val isAtLeastMarshmallow = sdkVersionInt >= Build.VERSION_CODES.M
override val isAtLeastLollipopMR1 = sdkVersionInt >= Build.VERSION_CODES.LOLLIPOP_MR1
override val isAtLeastLollipop = sdkVersionInt >= Build.VERSION_CODES.LOLLIPOP
override val isAtLeastKitKat = sdkVersionInt >= Build.VERSION_CODES.KITKAT
override val isAtLeastJellyBeanMR2 = sdkVersionInt >= Build.VERSION_CODES.JELLY_BEAN_MR2
override val isAtLeastJellyBeanMR1 = sdkVersionInt >= Build.VERSION_CODES.JELLY_BEAN_MR1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.