How can I detect when an Android application is running in the emulator?
How about this solution (class implementation of SystemProperties
is available here):
private var sIsProbablyRunningOnEmulator: Boolean? = nullfun isProbablyRunningOnEmulator(): Boolean { var result = sIsProbablyRunningOnEmulator if (result != null) return result // Android SDK emulator result = (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_")) // || 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") //bluestacks || "QC_Reference_Phone" == Build.BOARD && !"Xiaomi".equals(Build.MANUFACTURER, ignoreCase = true) //bluestacks || Build.MANUFACTURER.contains("Genymotion") || Build.HOST=="Build2" //MSI App Player || Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic") || Build.PRODUCT == "google_sdk" // another Android SDK emulator check || SystemProperties.getProp("ro.kernel.qemu") == "1" sIsProbablyRunningOnEmulator = result return result}
Note that some emulators fake exact specs of real devices, so it might be impossible to detect it. I've added what I could, but I don't think there is a 100% way to detect if it's really an emulator or not.
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"
Well Android id does not work for me, I'm currently using:
"google_sdk".equals( Build.PRODUCT );