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


当前回答

另一个选择是检查你是在调试模式还是生产模式:

if (BuildConfig.DEBUG){日志。i(TAG,“我在调试模式”);}

简单可靠。

这并不是问题的全部答案,但在大多数情况下,您可能想要区分用户群的调试/测试会话和生命会话。

在我的情况下,我在调试模式下将谷歌分析设置为dryRun(),因此这种方法完全适合我。


对于更高级的用户,还有另一种选择。Gradle构建变量:

在你的应用程序的gradle文件中添加一个新的变体:

buildTypes {
    release {
        // some already existing commands
    }
    debug {
        // some already existing commands
    }
    // the following is new
    test {
    }
}

在你的代码中检查构建类型:

if ("test".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Test build type"); }
 else if ("debug".equals(BuildConfig.BUILD_TYPE)) { Log.i(TAG, "I am in Debug build type"); }

现在你有机会构建3种不同类型的应用程序。

其他回答

我的建议:

试试github上的这个。

易于检测android模拟器

在设备场(https://aws.amazon.com/device-farm/)的真实设备上检查 BlueStacks Genymotion Android模拟器 安迪46.2.207.0 菜单玩 诺克斯应用播放器 Koplayer …

如何与示例一起使用:

EmulatorDetector.with(this)
                .setCheckTelephony(true)
                .addPackageName("com.bluestacks")
                .setDebug(true)
                .detect(new EmulatorDetector.OnEmulatorDetectorListener() {
                    @Override
                    public void onResult(boolean isEmulator) {
                        if(isEmulator){
                         // Do your work
                        }
                        else{
                        // Not emulator and do your work
                        }
                    }
                });

我尝试了几种技术,但最终选择了稍微修改过的检查Build的版本。产品如下。这似乎变化很大,从模拟器到模拟器,这就是为什么我有3个检查,我目前有。我想我本可以只检查product.contains("sdk"),但认为下面的检查更安全一些。

public static boolean isAndroidEmulator() {
    String model = Build.MODEL;
    Log.d(TAG, "model=" + model);
    String product = Build.PRODUCT;
    Log.d(TAG, "product=" + product);
    boolean isEmulator = false;
    if (product != null) {
        isEmulator = product.equals("sdk") || product.contains("_sdk") || product.contains("sdk_");
    }
    Log.d(TAG, "isEmulator=" + isEmulator);
    return isEmulator;
}

供你参考——我发现我的Kindle Fire有Build功能。BRAND = "generic",一些模拟器没有网络运营商的"Android"。

Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")

如果应用程序在模拟器上运行,这应该返回true。

我们应该注意的是不要检测所有的模拟器,因为只有几个不同的模拟器。这很容易检查。 我们必须确保实际的设备不会被检测为模拟器。

我使用名为“Android设备信息共享”的应用程序来检查这一点。

在这个应用程序上,你可以看到许多设备的各种信息(可能是世界上大多数设备;如果您正在使用的设备不在列表中,它将自动添加)。

if (Build.BRAND.equalsIgnoreCase("generic")) {
    // Is the emulator
}

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

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

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

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

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

所以,你可以这样检查:

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

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