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


当前回答

在Android Studio下[运行>编辑配置…]发射旗

在启动标志中添加以下内容…

--ei running_emulator 1

然后在你的onCreate活动中

Bundle extras = getIntent().getExtras();
if (extras.getInt("running_emulator", 0) == 1) {
   //Running in the emulator!... Make USE DEV ENV!!
}

简单!

其他回答

我找到了新的模拟器Build。硬件= "ranchu"。

参考:https://groups.google.com/forum/ # !主题/ android-emulator-dev / dltBnUW_HzU

而且我还找到了Android官方的方法来检查是否是模拟器。我认为这对我们是很好的参考。

Android API Level 23 [Android 6.0]

package com.android.internal.util;

/**
 * @hide
 */
public class ScreenShapeHelper {
    private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish");
}

我们有ScreenShapeHelper。IS_EMULATOR来检查emulator是否。

Android API Level 24 [Android 7.0]

package android.os;

/**
 * Information about the current build, extracted from system properties.
 */
public class Build {


    /**
     * Whether this build was for an emulator device.
     * @hide
     */
    public static final boolean IS_EMULATOR = getString("ro.kernel.qemu").equals("1");

}

我们有Build。IS_EMULATOR来检查emulator是否。

官方检查模拟器的方式是不是新的,也可能不够,上面的答案也提到了。

但这可能告诉我们,官方将提供官方检查是否模拟器的方法。

正如使用上面提到的所有方法一样,现在我们也可以使用这两种方法来检查模拟器是否正确。

如何访问com.android.internal包和@hide

并等待官方的开放SDK。

实际上,ANDROID_ID在2.2上总是等于9774D56D682E549C(根据这个线程+我自己的实验)。

所以,你可以这样检查:

String androidID = ...;
if(androidID == null || androidID.equals("9774D56D682E549C"))
    do stuff;

虽然不是最漂亮的,但也很管用。

这个方法对我有用

    public static boolean isRunningOnEmulator(String fingerprint, String hardware, String manufacturer) {
    boolean isEmulatorFingerprint = fingerprint.endsWith("test-keys");
    boolean isHardware = hardware.toLowerCase().contains("intel") || hardware.toLowerCase().contains("vbox");
    boolean isEmulatorManufacturer = manufacturer.equals("Genymotion")
            || manufacturer.equals("unknown");

    if (isHardware || isEmulatorFingerprint && isEmulatorManufacturer) {
        return true;
    } else {
        return false;
    }
}
if (Build.BRAND.equalsIgnoreCase("generic")) {
    // Is the emulator
}

所有BUILD引用都是BUILD。道具值,所以你必须考虑到如果你要把这个放到发布代码中,你可能会有一些根用户因为某种原因修改了他们的。实际上没有任何修改需要使用generic作为品牌,除非特别尝试模拟模拟器。

指纹是构建编译和内核编译签名。有一些构建使用通用的,通常直接来自谷歌。

在修改过的设备上,IMEI也有可能被归零,所以这是不可靠的,除非您完全阻止修改过的设备。

金鱼是所有其他设备扩展的基础android构建。每个Android设备都有一个init.金鱼.rc,除非被黑客攻击并出于未知原因删除。

上面建议的检查ANDROID_ID的解决方案对我来说很有效,直到我今天更新到Android 2.2发布的最新SDK工具。

因此,我目前切换到以下解决方案,到目前为止,缺点是你需要把PHONE_STATE读取权限(<uses-permission android:name="android.permission. read_phone_state "/>)

private void checkForDebugMode() {
    ISDEBUGMODE = false; //(Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID) == null);

    TelephonyManager man = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
    if(man != null){
        String devId = man.getDeviceSoftwareVersion();
        ISDEBUGMODE = (devId == null);
    }
}