I would like to have my code run slightly differently when running on the emulator than when running on a device. (For example, using 10.0.2.2 instead of a
How about this solution (class implementation of SystemProperties is available here):
fun isProbablyAnEmulator(): Boolean {
return (Build.FINGERPRINT.startsWith("google/sdk_gphone_")
&& Build.FINGERPRINT.endsWith(":user/release-keys")
&& Build.MANUFACTURER == "Google" && Build.PRODUCT.startsWith("sdk_gphone_") && Build.BRAND == "google"
&& Build.MODEL.startsWith("sdk_gphone_")) // Android SDK emulator
|| Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| "QC_Reference_Phone" == Build.BOARD //bluestacks
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.HOST.startsWith("Build") //MSI App Player
|| Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")
|| Build.PRODUCT == "google_sdk"
|| SystemProperties.getProp("ro.kernel.qemu") == "1"// another Android SDK emulator check
}
Note that some emulators fake exact specs of real devices, so it might be impossible to detect it.
Here a tiny snippet you can make in the APK to show various things about it, so you could add your own rules:
textView.text = "FINGERPRINT:${Build.FINGERPRINT}\n" +
"MODEL:${Build.MODEL}\n" +
"MANUFACTURER:${Build.MANUFACTURER}\n" +
"BRAND:${Build.BRAND}\n" +
"DEVICE:${Build.DEVICE}\n" +
"BOARD:${Build.BOARD}\n" +
"HOST:${Build.HOST}\n" +
"PRODUCT:${Build.PRODUCT}\n"