16

I have read this stackoverflow thread already and I tried using the code given in that answer to find out if I run my code on the emulator or on a real device:

import android.content.ContentResolver;
import android.provider.Settings.Secure;
...     
mTextView.setText(Secure.getString(getContentResolver(), Secure.ANDROID_ID));

On my real device it returns "2bccce3...", however on the emulator it does not return null, but also a string "bd9f8..."

Ideas how to find out if emulator or real device from code would be highly appreciated

Community
  • 1
  • 1
Addi
  • 1,099
  • 1
  • 12
  • 17

9 Answers9

18

This should do it:

boolean inEmulator = false;
String brand = Build.BRAND;
if (brand.compareTo("generic") == 0)
{
    inEmulator = true;
}

EDIT:

boolean inEmulator = "generic".equals(Build.BRAND.toLowerCase());
A. Abiri
  • 10,750
  • 4
  • 30
  • 31
  • 1
    Yes, I think that is more reliable than the other methods I found. I'm pretty sure, though, that nobody has put in writing that this will always be true of emulators. (I'm willing to bet that it will be false for all devices, although probably nobody is guaranteeing that, either.) As an aside, I think your code would be clearar as a one-liner: `boolean inEmulator = "generic".equals(Build.BRAND);`. – Ted Hopp Jul 28 '11 at 21:31
  • Edited it to make it more clear. Thanks for the advice. Also, I think this should work for a least a majority of devices, since I tested this on the emulator for 1.5, 1.6, and 2.1, and it worked. – A. Abiri Jul 28 '11 at 21:44
  • I tested it on a 2.3.3 emulator as well. I also tested it on Samsung's Galaxy Tab and Sony Erikson's ETK emulators and it works well. But who knows if it will work into the future. – Ted Hopp Jul 28 '11 at 23:43
  • Well, I don't think there is any reason for the value to change in the future. It would seem reasonable for all the emulators to keep the value the same. It would just complicate things if there are any differences. – A. Abiri Jul 29 '11 at 05:21
  • This will serve my needs, although, as @Ted mentioned "who knows if it will work into the future". I need to know if I am on a real device to assure I don't run debug code. I would not think that a HW device BRAND is called "generic". If that changed for the emulator in the future, I would simply adapt my code. So fine for me. Question answered. Thanks Arash – Addi Jul 29 '11 at 07:35
  • Just for info, if you are using accelerated x86 emulator, brand will be "generic_x86". Therefore I use Build.BRAND.toLowerCase().startsWith("generic"); (Is that safe? Has anyone ever seen a device with null brand?) – daemontus Aug 27 '14 at 10:40
9

With the advent of the new Intel native emulator the above mentioned methods did not work any longer. Now I am using this code snippet which works on both Intel and ARM emulators:

if (Build.MODEL.contains("google_sdk") ||
    Build.MODEL.contains("Emulator") ||
    Build.MODEL.contains("Android SDK")) {
  RunsInEmulator = true;
}
Ernie
  • 1,210
  • 1
  • 14
  • 21
7

There's a rather old thread on Android Developers group that suggests checking the number of sensors on the device. Something like this might work:

SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (manager.getSensorList(Sensor.TYPE_ALL).isEmpty()) {
    // running on an emulator
} else {
    // running on a device
}

I haven't tried this, so I have no idea how reliable the suggestion is. (Perhaps some emulators now report some sensors; perhaps some devices report no sensors. [Is there an Android toothbrush yet?]) But it can't be worse than checking for a null ANDROID_ID (which doesn't work as of 2.2).

P.S. Another thread claims that as of 2.2, the ANDROID_ID for the emulator is always "9774D56D682E549C". However, you are apparently getting some other hex string, so I don't think this is right, either.

P.P.S. Other suggestions I haven't tried are here. One that seems particularly nice (if it works) is:

if (android.os.Build.MODEL.equals(“google_sdk”)) {
   // emulator
} else {
   //not emulator
}
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • I have tried the one given in P.P.S. above on a 3.0 emulator (with Google maps API) and on devices Nexus One, Motorola defy, and Samsung Galaxy S. It works as expected. This should fit my purposes, even if the MODEL of the emulator would change in the future, I would adapt. Only one thing most not happen: The app asuming to run on an emulator if its a real device. However it's rather unlikely that a real device MODEL is named “google_sdk”. SO this solves my problem. Thanks much Ted – Addi Jul 29 '11 at 07:16
  • Sensor check did not worked for me. Emulator's sensorlist did not come up empty but acted like a device. – Serdar Samancıoğlu Dec 26 '12 at 09:16
2

How about this solution:

  public static boolean isRunningOnEmulator()
    {
    boolean result=//
        Build.FINGERPRINT.startsWith("generic")//
            ||Build.FINGERPRINT.startsWith("unknown")//
            ||Build.MODEL.contains("google_sdk")//
            ||Build.MODEL.contains("Emulator")//
            ||Build.MODEL.contains("Android SDK built for x86");
    if(result)
      return true;
    result|=Build.BRAND.startsWith("generic")&&Build.DEVICE.startsWith("generic");
    if(result)
      return true;
    result|="google_sdk".equals(Build.PRODUCT);
    return result;
    }

EDIT: seems I've answered this already, here:

https://stackoverflow.com/a/21505193/878126

android developer
  • 114,585
  • 152
  • 739
  • 1,270
2

I think that the best answer is to decide why you actually care to know - and then check for whatever specific characteristic of the emulator you believe requires that your app behave differently than it would on a device.

Chris Stratton
  • 39,853
  • 6
  • 84
  • 117
  • I need to run debug code in emulator mode.
    So what I need is something that definitely tells me that I am on a real device, to assure the "real code" is executed. If a check for the emulator would fail in the futur, not a big problem, I could easily adapt.
    @Ted as given a trial in the P.P.S of his answer, which works for my purposes, see my comment to his answer
    – Addi Jul 29 '11 at 07:26
  • I'd recommend you separate debugging from emulator/device, because there may be times you'll find you need to run debug code on a real device when it exposes a problem the emulator didn't. – Chris Stratton Jul 29 '11 at 13:59
1

As stated in this post, IMEI and IMSI are harcoded on the emulator:

2325     { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL },   /* request internation subscriber identification number */
2326     { "+CGSN", "000000000000000", NULL },   /* request model version */



You can easily get the value using

adb shell dumpsys iphonesubinfo

So checking the device's IMEI using TelephonyManager.getDeviceId() should be sufficient to find out, whether you're on an emulator or a real device.


To be absolutely sure, you might combine it with checking the model name as stated by various other posts.

public static boolean isRunningOnEmulator(final Context inContext) {

    final TelephonyManager theTelephonyManager = (TelephonyManager)inContext.getSystemService(Context.TELEPHONY_SERVICE);
    final boolean hasEmulatorImei = theTelephonyManager.getDeviceId().equals("000000000000000");
    final boolean hasEmulatorModelName = Build.MODEL.contains("google_sdk")
            || Build.MODEL.contains("Emulator")
            || Build.MODEL.contains("Android SDK");

    return hasEmulatorImei || hasEmulatorModelName;
}


The downside to this approach is that you need a context to access this information and instantiating a TelephonyManager for every check.

Community
  • 1
  • 1
Father Stack
  • 524
  • 3
  • 10
1

This is the standard google flutter emulator check :

public 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");
}
kmno
  • 85
  • 7
0

Following one is correctly detect my emulator

if (Build.BRAND.equalsIgnoreCase("generic")) {
              //"YES, I am an emulator"
       } else {
              //"NO, I am NOT an emulator"
       }
multi
  • 1
  • 2
0

As of writing this, nothing in this thread worked for the Bluestacks 4 emulator except trying to check for sensors. And so I checked the battery temperature using this gist. It should return 0.0 which means it does not have a battery temperature (and therefore it's an emulator).

public float getCpuTemp() {
    Process process;
    try {
        process = Runtime.getRuntime().exec("cat sys/class/thermal/thermal_zone0/temp");
        process.waitFor();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line = reader.readLine();
        float temp = Float.parseFloat(line) / 1000.0f;
        return temp;
    } catch (Exception e) {
        e.printStackTrace();
        return 0.0f;
    }
}
Sha-agi
  • 184
  • 2
  • 5
  • I should also note that this encompasses all emulators. For Bluestacks 4 you can create a function to detect the `windows` folder in the sdcard. – Sha-agi Feb 19 '19 at 04:03