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


当前回答

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

其他回答

我从来没有找到一个很好的方法来判断你是否在模拟器中。

但如果你只是需要检测你是否在开发环境中,你可以这样做:

     if(Debug.isDebuggerConnected() ) {
        // Things to do in debug environment...
    }

希望对大家有所帮助....

以下是我的解决方案(它只适用于在调试机器上运行web服务器): 我已经创建了一个后台任务,当应用程序启动时启动。它查找http://10.0.2.2,如果它存在,它将全局参数(IsDebug)更改为true。这是一种无声的方式来找出你在哪里跑步。

public class CheckDebugModeTask extends AsyncTask<String, Void, String> {
public static boolean IsDebug = false;

public CheckDebugModeTask()
{

}

@Override
protected String doInBackground(String... params) {     
  try {
    HttpParams httpParameters = new BasicHttpParams();
    int timeoutConnection = 1000;
    HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
    int timeoutSocket = 2000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    String url2 = "http://10.0.2.2";        
          HttpGet httpGet = new HttpGet(url2);
    DefaultHttpClient client = new DefaultHttpClient(httpParameters);

    HttpResponse response2 = client.execute(httpGet);
    if (response2 == null || response2.getEntity() == null || response2.getEntity().getContent() == null)
    return "";

    return "Debug";

} catch (Exception e) {
    return "";
}
}

@Override
protected void onPostExecute (String result)
{       
if (result == "Debug")
{
    CheckDebugModeTask.IsDebug = true;
}
}

从主活动onCreate:

CheckDebugModeTask checkDebugMode = new CheckDebugModeTask();
checkDebugMode.execute("");

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

所以,你可以这样检查:

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

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

所有答案都在一个方法中

static boolean checkEmulator()
{
    try
    {
        String buildDetails = (Build.FINGERPRINT + Build.DEVICE + Build.MODEL + Build.BRAND + Build.PRODUCT + Build.MANUFACTURER + Build.HARDWARE).toLowerCase();

        if (buildDetails.contains("generic") 
        ||  buildDetails.contains("unknown") 
        ||  buildDetails.contains("emulator") 
        ||  buildDetails.contains("sdk") 
        ||  buildDetails.contains("genymotion") 
        ||  buildDetails.contains("x86") // this includes vbox86
        ||  buildDetails.contains("goldfish")
        ||  buildDetails.contains("test-keys"))
            return true;
    }   
    catch (Throwable t) {Logger.catchedError(t);}

    try
    {
        TelephonyManager    tm  = (TelephonyManager) App.context.getSystemService(Context.TELEPHONY_SERVICE);
        String              non = tm.getNetworkOperatorName().toLowerCase();
        if (non.equals("android"))
            return true;
    }
    catch (Throwable t) {Logger.catchedError(t);}

    try
    {
        if (new File ("/init.goldfish.rc").exists())
            return true;
    }
    catch (Throwable t) {Logger.catchedError(t);}

    return false;
}

我找到了新的模拟器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。