How can I detect when an Android application is running in the emulator?
Solution 1:
How about this solution (class implementation of SystemProperties
is available here):
private var sIsProbablyRunningOnEmulator: Boolean? = null
fun 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"
Solution 2:
One common one sems to be Build.FINGERPRINT.contains("generic")
Solution 3:
Well Android id does not work for me, I'm currently using:
"google_sdk".equals( Build.PRODUCT );
Solution 4:
Google uses this code in the device-info plugin from Flutter to determine if the device is an emulator:
private boolean isEmulator() {
return (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
|| Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.HARDWARE.contains("goldfish")
|| Build.HARDWARE.contains("ranchu")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.MANUFACTURER.contains("Genymotion")
|| Build.PRODUCT.contains("sdk_google")
|| Build.PRODUCT.contains("google_sdk")
|| Build.PRODUCT.contains("sdk")
|| Build.PRODUCT.contains("sdk_x86")
|| Build.PRODUCT.contains("sdk_gphone64_arm64")
|| Build.PRODUCT.contains("vbox86p")
|| Build.PRODUCT.contains("emulator")
|| Build.PRODUCT.contains("simulator");
}
Solution 5:
Based on hints from other answers, this is probably the most robust way:
isEmulator = "goldfish".equals(Build.HARDWARE)