How can I detect when an Android application is running in the emulator?

前端 未结 30 2326
无人及你
无人及你 2020-11-22 16:42

I would like to have my code run slightly differently when running on the emulator than when running on a device. (For example, using 10.0.2.2 instead of a

相关标签:
30条回答
  • 2020-11-22 17:33

    All answers in one method

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 17:34

    Here is my solution (it works only if you run a web server on your debug machine): I have created a background task that starts when the application starts. It looks for http://10.0.2.2 and if it exists it changes a global parameter (IsDebug) to true. It is a silent way to find out where you are running.

    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;
    }
    }
    

    from the main activity onCreate:

    CheckDebugModeTask checkDebugMode = new CheckDebugModeTask();
    checkDebugMode.execute("");
    
    0 讨论(0)
  • 2020-11-22 17:35

    From Battery, the emulator: Power source is always AC Charger. Temperature is always 0.

    And you can use Build.HOST to record host value, different emulator has different host value.

    0 讨论(0)
  • 2020-11-22 17:35

    Since the underlying emulation engine for Genymotion is VirtualBox and that's not going to change any time soon I found the following code the most reliable:

       public static boolean isGenymotion() {
            return Build.PRODUCT != null && Build.PRODUCT.contains("vbox");
    }
    
    0 讨论(0)
  • 2020-11-22 17:36

    Whichever code you use to do emulator detection, I'd highly recommend writing unit tests to cover all the Build.FINGERPRINT, Build.HARDWARE and Build.MANUFACTURER values that you are depending on. Here are some example tests:

    @Test
    public void testIsEmulatorGenymotion() throws Exception {
        assertThat(
                DeviceUtils.isRunningOnEmulator(
                        "generic/vbox86p/vbox86p:4.1.1/JRO03S/eng.buildbot.20150217.102902:userdebug/test-keys",
                        "vbox86", "Genymotion")).isTrue();
    
        assertThat(
                DeviceUtils.isRunningOnEmulator(
                        "generic/vbox86p/vbox86p:5.1/LMY47D/buildbot06092001:userdebug/test-keys", "vbox86",
                        "Genymotion")).isTrue();
    }
    
    @Test
    public void testIsEmulatorDefaultAndroidEmulator() throws Exception {
        assertThat(
                DeviceUtils.isRunningOnEmulator(
                        "generic_x86/sdk_google_phone_x86/generic_x86:5.0.2/LSY66H/1960483:eng/test-keys", "goldfish",
                        "unknown")).isTrue();
    
        assertThat(
                DeviceUtils.isRunningOnEmulator(
                        "Android/sdk_google_phone_x86_64/generic_x86_64:6.0/MASTER/2469028:userdebug/test-keys",
                        "ranchu", "unknown")).isTrue();
    }
    
    @Test
    public void testIsEmulatorRealNexus5() throws Exception {
        assertThat(
                DeviceUtils.isRunningOnEmulator("google/hammerhead/hammerhead:6.0.1/MMB29K/2419427:user/release-keys",
                        "hammerhead", "LGE")).isFalse();
    }
    

    ...and here's our code (debug logs and comments removed for conciseness):

    public static boolean isRunningOnEmulator() {
        if (sIsRunningEmulator == null) {
            sIsRunningEmulator = isRunningOnEmulator(Build.FINGERPRINT, Build.HARDWARE, Build.MANUFACTURER);
        }
    
        return sIsRunningEmulator;
    }
    
    static boolean isRunningOnEmulator(String fingerprint, String hardware, String manufacturer) {
        boolean isEmulatorFingerprint = fingerprint.endsWith("test-keys");
        boolean isEmulatorManufacturer = manufacturer.equals("Genymotion")
                || manufacturer.equals("unknown");
    
        if (isEmulatorFingerprint && isEmulatorManufacturer) {
            return true;
        } else {
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 17:38

    Well Android id does not work for me, I'm currently using:

    "google_sdk".equals( Build.PRODUCT );
    
    0 讨论(0)
提交回复
热议问题