Как узнать код, если приложение для Android работает на эмуляторе или на реальном устройстве?
Я уже прочитал qaru.site/info/369258/..., и я попытался использовать код, указанный в этом ответе, чтобы узнать, запускаю ли я свой код на эмуляторе или на реальном устройстве
import android.content.ContentResolver;
import android.provider.Settings.Secure;
...
mTextView.setText(Secure.getString(getContentResolver(), Secure.ANDROID_ID));
На моем реальном устройстве он возвращает "2bccce3...", однако на эмуляторе он не возвращает null, но также строку "bd9f8..."
Идеи, как узнать, будет ли высоко оценен эмулятор или реальное устройство из кода.
Ответы
Ответ 1
Там довольно старый поток в группе разработчиков Android, который предлагает проверить количество датчиков на устройстве. Возможно, что-то подобное:
SensorManager manager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (manager.getSensorList(Sensor.TYPE_ALL).isEmpty()) {
// running on an emulator
} else {
// running on a device
}
Я не пробовал этого, поэтому я понятия не имею, насколько надежным является это предложение. (Возможно, некоторые эмуляторы теперь сообщают о некоторых датчиках, возможно, некоторые устройства не сообщают никаких датчиков. [Есть еще зубная щетка для Android?]) Но это не может быть хуже, чем проверка нулевого ANDROID_ID (который не работает с 2.2).
P.S. Другой поток утверждает, что с 2.2, ANDROID_ID для эмулятора всегда "9774D56D682E549C". Тем не менее, вы, видимо, получаете еще одну шестую строку, поэтому я не думаю, что это тоже так.
P.P.S. Другие предложения, которые я не пробовал, здесь. Особенно приятно (если он работает):
if (android.os.Build.MODEL.equals("google_sdk")) {
// emulator
} else {
//not emulator
}
Ответ 2
Это должно сделать это:
boolean inEmulator = false;
String brand = Build.BRAND;
if (brand.compareTo("generic") == 0)
{
inEmulator = true;
}
EDIT:
boolean inEmulator = "generic".equals(Build.BRAND.toLowerCase());
Ответ 3
С появлением нового встроенного эмулятора Intel вышеупомянутые методы больше не работали. Теперь я использую этот фрагмент кода, который работает как на эмуляторах Intel, так и на ARM:
if (Build.MODEL.contains("google_sdk") ||
Build.MODEL.contains("Emulator") ||
Build.MODEL.contains("Android SDK")) {
RunsInEmulator = true;
}
Ответ 4
Я думаю, что лучший ответ - решить, почему вы действительно хотите знать, - а затем проверить, какая конкретная характеристика эмулятора, по вашему мнению, требует, чтобы ваше приложение выглядело иначе, чем на устройстве.
Ответ 5
Как насчет этого решения:
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;
}
Ответ 6
Как указано в этом сообщении, IMEI и IMSI кодируются на эмуляторе:
2325 { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL }, /* request internation subscriber identification number */
2326 { "+CGSN", "000000000000000", NULL }, /* request model version */
Вы можете легко получить значение, используя
adb shell dumpsys iphonesubinfo
Таким образом, проверки устройства IMEI с помощью TelephonyManager.getDeviceId() должно быть достаточно, чтобы узнать, используете ли вы эмулятор или реального устройства.
Чтобы быть абсолютно уверенным, вы можете объединить его с проверкой имени модели, как указано в других других сообщениях.
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;
}
Недостатком этого подхода является то, что вам нужен контекст для доступа к этой информации и создания экземпляра TelephonyManager для каждой проверки.
Ответ 7
Следующее одно правильно обнаруживает мой эмулятор
if (Build.BRAND.equalsIgnoreCase("generic")) {
//"YES, I am an emulator"
} else {
//"NO, I am NOT an emulator"
}
Ответ 8
На момент написания статьи в этом эмуляторе Bluestacks 4 ничего не работало, кроме попыток проверки датчиков. И поэтому я проверил температуру батареи, используя эту суть. Он должен возвращать 0.0
что означает, что у него нет температуры батареи (и, следовательно, это эмулятор).
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;
}
}
Ответ 9
Это стандартная проверка эмулятора Google Flutter:
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");
}