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

前端 未结 30 2325
无人及你
无人及你 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:20

    Another option is to check if you are in debug mode or production mode:

    if (BuildConfig.DEBUG) { Log.i(TAG, "I am in debug mode"); }

    simple and reliable.

    Not totally the answer of the question but in most cases you may want to distinguish between debugging/test sessions and life sessions of your user base.

    In my case I set google analytics to dryRun() when in debug mode so this approach works totally fine for me.


    For more advanced users there is another option. gradle build variants:

    in your app's gradle file add a new variant:

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

    In your code check the build type:

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

    Now you have the opportunity to build 3 different types of your app.

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

    Checking the answers, none of them worked when using LeapDroid, Droid4x or Andy emulators,

    What does work for all cases is the following:

     private static String getSystemProperty(String name) throws Exception {
        Class systemPropertyClazz = Class.forName("android.os.SystemProperties");
        return (String) systemPropertyClazz.getMethod("get", new Class[]{String.class}).invoke(systemPropertyClazz, new Object[]{name});
    }
    
    public boolean isEmulator() {
        boolean goldfish = getSystemProperty("ro.hardware").contains("goldfish");
        boolean emu = getSystemProperty("ro.kernel.qemu").length() > 0;
        boolean sdk = getSystemProperty("ro.product.model").equals("sdk");
        return goldfish || emu || sdk;
    }
    
    0 讨论(0)
  • 2020-11-22 17:22

    Google uses this code in the device-info plugin from Flutter to determine if the device is an emulator:

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

    I tried several techniques, but settled on a slightly revised version of checking the Build.PRODUCT as below. This seems to vary quite a bit from emulator to emulator, that's why I have the 3 checks I currently have. I guess I could have just checked if product.contains("sdk") but thought the check below was a bit safer.

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

    FYI - I found that my Kindle Fire had Build.BRAND = "generic", and some of the emulators didn't have "Android" for the network operator.

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

    I found the new emulator Build.HARDWARE = "ranchu".

    Reference:https://groups.google.com/forum/#!topic/android-emulator-dev/dltBnUW_HzU

    And also I found the Android official way to check whether emulator or not.I think it's good reference for us.

    Since 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");
    }
    

    We have ScreenShapeHelper.IS_EMULATOR to check whether emulator.

    Since 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");
    
    }
    

    We have Build.IS_EMULATOR to check whether emulator.

    The way the official to check whether emulator is not new,and also maybe not enough,the answers above also mentioned.

    But this maybe show us that the official will provide the way of official to check whether emulator or not.

    As using the above all ways mentioned,right now we can also use the two ways about to check whether emulator.

    How to access the com.android.internal package and @hide

    and wait for the official open SDK.

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

    Another option would be to look at the ro.hardware property and see if its set to goldfish. Unfortunately there doesn't seem to be an easy way to do this from Java but its trivial from C using property_get().

    0 讨论(0)
提交回复
热议问题