我希望我的代码在模拟器上运行时与在设备上运行时略有不同。(例如,使用10.0.2.2代替公共URL在开发服务器上自动运行。)检测Android应用程序何时在模拟器中运行的最佳方法是什么?


当前回答

这对我来说是有效的,而不是startwith: Build.FINGERPRINT.contains("generic")

欲了解更多信息,请查看这个链接:https://gist.github.com/espinchi/168abf054425893d86d1

其他回答

您可以检查deviceId (IMEI)是否为“000000000000000”(15个零)

使用这个函数:

 public static final boolean isEmulator() {

    int rating = 0;

    if ((Build.PRODUCT.equals("sdk")) || (Build.PRODUCT.equals("google_sdk"))
            || (Build.PRODUCT.equals("sdk_x86")) || (Build.PRODUCT.equals("vbox86p"))) {
        rating++;
    }
    if ((Build.MANUFACTURER.equals("unknown")) || (Build.MANUFACTURER.equals("Genymotion"))) {
        rating++;
    }
    if ((Build.BRAND.equals("generic")) || (Build.BRAND.equals("generic_x86"))) {
        rating++;
    }
    if ((Build.DEVICE.equals("generic")) || (Build.DEVICE.equals("generic_x86")) || (Build.DEVICE.equals("vbox86p"))) {
        rating++;
    }
    if ((Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk"))
            || (Build.MODEL.equals("Android SDK built for x86"))) {
        rating++;
    }
    if ((Build.HARDWARE.equals("goldfish")) || (Build.HARDWARE.equals("vbox86"))) {
        rating++;
    }
    if ((Build.FINGERPRINT.contains("generic/sdk/generic"))
            || (Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86"))
            || (Build.FINGERPRINT.contains("generic/google_sdk/generic"))
            || (Build.FINGERPRINT.contains("generic/vbox86p/vbox86p"))) {
        rating++;
    }

    return rating > 4;

    }

最常用的方法是从品牌、名称……等。但是这个方法是静态的,并且适用于模拟器的有限版本。如果有1000多家虚拟机制造商呢?那么你必须写一段代码来匹配1000多个虚拟机?

但这是浪费时间。甚至在一段时间后,会有新的vm启动,你的脚本也会被浪费。

根据我的测试,我知道了 getRadioVersion()在虚拟机上返回空, 并返回版本号在真正的android设备。

public Boolean IsVM() 
{
    return android.os.Build.getRadioVersion().length() == 0;
} 
//return true if VM
//return false if real

虽然有用,但我没有官方解释。

代码:http://github.com/Back-X/anti-vm/blob/main/android/anti-vm.b4a

发布:http://github.com/Back-X/anti-vm/releases/download/1/anti-vm.apk

在模拟器的文件系统中放入一个文件;由于该文件不会存在于真正的设备上,这应该是稳定的,可靠的,容易修复当它崩溃。

这个代码适用于我

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String networkOperator = tm.getNetworkOperatorName();
if("Android".equals(networkOperator)) {
    // Emulator
}
else {
    // Device
}

如果该设备没有sim卡,它将返回空字符串:""

由于Android模拟器总是返回“Android”作为网络运营商,我使用上面的代码。