如果我的Android应用程序在模拟器或真实设备上运行,如何从代码中找出?

时间:2011-07-28 19:00:22

标签: android emulation

我已经阅读了this stackoverflow thread,我尝试使用该答案中给出的代码来查明我是在模拟器上还是在真实设备上运行我的代码:

import android.content.ContentResolver;
import android.provider.Settings.Secure;
...     
mTextView.setText(Secure.getString(getContentResolver(), Secure.ANDROID_ID));

在我的真实设备上它返回“2bccce3 ...”,但是在模拟器上它不会返回null,而是一个字符串“bd9f8 ...”

如何从代码中找出仿真器或真实设备的想法将受到高度赞赏

9 个答案:

答案 0 :(得分:18)

这应该这样做:

boolean inEmulator = false;
String brand = Build.BRAND;
if (brand.compareTo("generic") == 0)
{
    inEmulator = true;
}

修改

boolean inEmulator = "generic".equals(Build.BRAND.toLowerCase());

答案 1 :(得分:9)

随着新的英特尔本机模拟器的出现,上述方法不再适用。现在我使用的代码片段适用于Intel和ARM仿真器:

if (Build.MODEL.contains("google_sdk") ||
    Build.MODEL.contains("Emulator") ||
    Build.MODEL.contains("Android SDK")) {
  RunsInEmulator = true;
}

答案 2 :(得分:6)

有一个相当古老的thread on Android Developers group建议检查设备上的传感器数量。这样的事情可能有用:

SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (manager.getSensorList(Sensor.TYPE_ALL).isEmpty()) {
    // running on an emulator
} else {
    // running on a device
}

我没试过这个,所以我不知道这个建议有多可靠。 (也许有些仿真器现在会报告一些传感器;也许有些设备报告没有传感器。[还有Android牙刷吗?])但是它不能比检查一个空的ANDROID_ID(从2.2开始不起作用)更糟糕。

P.S。 Another thread声称从2.2开始,模拟器的ANDROID_ID始终为“9774D56D682E549C”。但是,你显然正在获得一些其他的十六进制字符串,所以我认为这也不对。

P.P.S。我没有尝试的其他建议是here。一个看起来特别好的(如果它有效)是:

if (android.os.Build.MODEL.equals(“google_sdk”)) {
   // emulator
} else {
   //not emulator
}

答案 3 :(得分:2)

我认为最好的答案是确定您真正关心的原因 - 然后检查模拟器的任何特定特征您认为应用程序的行为与设备上的行为不同

答案 4 :(得分:2)

这个解决方案怎么样:

  public static boolean isRunningOnEmulator()
    {
    boolean result=//
        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");
    if(result)
      return true;
    result|=Build.BRAND.startsWith("generic")&&Build.DEVICE.startsWith("generic");
    if(result)
      return true;
    result|="google_sdk".equals(Build.PRODUCT);
    return result;
    }

答案 5 :(得分:1)

this post中所述,IMEI和IMSI在模拟器上进行了编码:

2325     { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL },   /* request internation subscriber identification number */
2326     { "+CGSN", "000000000000000", NULL },   /* request model version */



您可以使用

轻松获取值
adb shell dumpsys iphonesubinfo

因此,使用TelephonyManager.getDeviceId()检查设备的IMEI应该足以找出您是在模拟器还是真实设备上。

为了绝对确定,您可以将其与检查各种其他帖子所述的型号名称相结合。

public static boolean isRunningOnEmulator(final Context inContext) {

    final TelephonyManager theTelephonyManager = (TelephonyManager)inContext.getSystemService(Context.TELEPHONY_SERVICE);
    final boolean hasEmulatorImei = theTelephonyManager.getDeviceId().equals("000000000000000");
    final boolean hasEmulatorModelName = Build.MODEL.contains("google_sdk")
            || Build.MODEL.contains("Emulator")
            || Build.MODEL.contains("Android SDK");

    return hasEmulatorImei || hasEmulatorModelName;
}


这种方法的缺点是您需要一个上下文来访问此信息并为每次检查实例化TelephonyManager。

答案 6 :(得分:1)

这是标准的 google flutter 模拟器检查:

public 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("vbox86p")
            || Build.PRODUCT.contains("emulator")
            || Build.PRODUCT.contains("simulator");
}

答案 7 :(得分:0)

以下是正确检测我的模拟器

if (Build.BRAND.equalsIgnoreCase("generic")) {
              //"YES, I am an emulator"
       } else {
              //"NO, I am NOT an emulator"
       }

答案 8 :(得分:0)

在撰写本文时,此线程中的任何东西都不能用于Bluestacks 4模拟器,除非尝试检查传感器。因此,我使用此gist检查了电池温度。它应该返回0.0,这表示它没有电池温度(因此是模拟器)。

public float getCpuTemp() {
    Process process;
    try {
        process = Runtime.getRuntime().exec("cat sys/class/thermal/thermal_zone0/temp");
        process.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        float temp = Float.parseFloat(line) / 1000.0f;
        return temp;
    } catch (Exception e) {
        e.printStackTrace();
        return 0.0f;
    }
}