una ultima studio puedo por pasar otro manager enviar emulator cómo compartir como celular aplicación aplicaciones aplicacion android android-emulator

ultima - ¿Cómo puedo detectar cuándo se está ejecutando una aplicación de Android en el emulador?



cómo puedo compartir una aplicación (30)

Me gustaría que mi código se ejecute de forma ligeramente diferente cuando se ejecuta en el emulador que cuando se ejecuta en un dispositivo. ( Por ejemplo , usar 10.0.2.2 en lugar de una URL pública para ejecutarse en un servidor de desarrollo automáticamente). ¿Cuál es la mejor manera de detectar cuándo se está ejecutando una aplicación de Android en el emulador?


¿Qué hay de esta solución:

public static boolean isEmulator() { return 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") || Build.MANUFACTURER.contains("Genymotion") || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) || "google_sdk".equals(Build.PRODUCT); }


¿Qué tal algo como el siguiente código para saber si su aplicación se firmó con la clave de depuración? ¿No está detectando el emulador pero podría funcionar para tu propósito?

public void onCreate Bundle b ) { super.onCreate(savedInstanceState); if ( signedWithDebugKey(this,this.getClass()) ) { blah blah blah } blah blah blah } static final String DEBUGKEY = "get the debug key from logcat after calling the function below once from the emulator"; public static boolean signedWithDebugKey(Context context, Class<?> cls) { boolean result = false; try { ComponentName comp = new ComponentName(context, cls); PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(),PackageManager.GET_SIGNATURES); Signature sigs[] = pinfo.signatures; for ( int i = 0; i < sigs.length;i++) Log.d(TAG,sigs[i].toCharsString()); if (DEBUGKEY.equals(sigs[0].toCharsString())) { result = true; Log.d(TAG,"package has been signed with the debug key"); } else { Log.d(TAG,"package signed with a key other than the debug key"); } } catch (android.content.pm.PackageManager.NameNotFoundException e) { return false; } return result; }


Al verificar las respuestas, ninguno de ellos funcionó al usar los emuladores LeapDroid, Droid4x o Andy,

Lo que sí funciona para todos los casos es lo siguiente:

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


Aquí está mi solución (funciona solo si ejecuta un servidor web en su máquina de depuración): He creado una tarea en segundo plano que comienza cuando se inicia la aplicación. Busca http://10.0.2.2 y, si existe, cambia un parámetro global (IsDebug) a verdadero. Es una forma silenciosa de averiguar dónde estás corriendo.

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

de la actividad principal onCreate:

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


Basado en sugerencias de otras respuestas, esta es probablemente la forma más robusta:

isEmulator = "goldfish".equals(Build.HARDWARE)


Bueno, la identificación de Android no funciona para mí, actualmente estoy usando:

"google_sdk".equals( Build.PRODUCT );


Cualquiera que sea el código que utilice para realizar la detección de emuladores, le recomiendo que escriba pruebas unitarias para cubrir todos los Build.FINGERPRINT , Build.HARDWARE y Build.MANUFACTURER que depende. Aquí hay algunos ejemplos de pruebas:

@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(); }

... y aquí está nuestro código (registros de depuración y comentarios eliminados por concisión):

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


Dado que el motor de emulación subyacente para Genymotion es VirtualBox y eso no va a cambiar en ningún momento, el siguiente código es el más confiable:

public static boolean isGenymotion() { return Build.PRODUCT != null && Build.PRODUCT.contains("vbox"); }


Desde la batería, el emulador: la fuente de alimentación es siempre el cargador de CA. La temperatura siempre es 0.

Y puede usar Build.HOST para registrar el valor del host, un emulador diferente tiene un valor de host diferente.


En realidad, ANDROID_ID en 2.2 siempre es igual a 9774D56D682E549C (según este hilo + mis propios experimentos).

Entonces, podrías revisar algo como esto:

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

No es el más bonito, pero hace el trabajo.


Encontré el nuevo emulador Build.HARDWARE = "ranchu" .

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

Y también encontré la forma oficial de Android para comprobar si emulador o no. Creo que es una buena referencia para nosotros.

Desde el nivel 23 de la API de Android [Android 6.0]

package com.android.internal.util; /** * @hide */ public class ScreenShapeHelper { private static final boolean IS_EMULATOR = Build.HARDWARE.contains("goldfish"); }

Tenemos ScreenShapeHelper.IS_EMULATOR para verificar si el emulador.

Desde el nivel 24 de la API de Android [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"); }

Tenemos Build.IS_EMULATOR para comprobar si emulador.

La forma en que el funcionario comprueba si el emulador no es nuevo, y quizás tampoco sea suficiente, las respuestas mencionadas anteriormente también se mencionan.

Pero esto tal vez nos muestre que el funcionario proporcionará la forma de oficial para verificar si el emulador o no.

Como utilizamos las formas mencionadas anteriormente, ahora también podemos usar las dos formas para verificar si el emulador.

Cómo acceder al paquete com.android.internal y @hide

y esperar el SDK oficial abierto.


Este código me funciona

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); String networkOperator = tm.getNetworkOperatorName(); if("Android".equals(networkOperator)) { // Emulator } else { // Device }

En caso de que el dispositivo no tenga tarjeta SIM, vuelve a aparecer una cadena vacía: ""

Como el emulador de Android siempre vuelve a funcionar "Android" como operador de red, uso el código anterior.


Esto funciona para mi

public boolean isEmulator() { return Build.MANUFACTURER.equals("unknown"); }


He recopilado todas las respuestas a esta pregunta y se me ocurrió una función para detectar si Android se está ejecutando en un vm / emulador:

public boolean isvm(){ StringBuilder deviceInfo = new StringBuilder(); deviceInfo.append("Build.PRODUCT " +Build.PRODUCT +"/n"); deviceInfo.append("Build.FINGERPRINT " +Build.FINGERPRINT+"/n"); deviceInfo.append("Build.MANUFACTURER " +Build.MANUFACTURER+"/n"); deviceInfo.append("Build.MODEL " +Build.MODEL+"/n"); deviceInfo.append("Build.BRAND " +Build.BRAND+"/n"); deviceInfo.append("Build.DEVICE " +Build.DEVICE+"/n"); String info = deviceInfo.toString(); Log.i("LOB", info); Boolean isvm = false; if( "google_sdk".equals(Build.PRODUCT) || "sdk_google_phone_x86".equals(Build.PRODUCT) || "sdk".equals(Build.PRODUCT) || "sdk_x86".equals(Build.PRODUCT) || "vbox86p".equals(Build.PRODUCT) || Build.FINGERPRINT.contains("generic") || Build.MANUFACTURER.contains("Genymotion") || Build.MODEL.contains("Emulator") || Build.MODEL.contains("Android SDK built for x86") ){ isvm = true; } if(Build.BRAND.contains("generic")&&Build.DEVICE.contains("generic")){ isvm = true; } return isvm; }

Probado en emulador, Genymotion y Bluestacks (1 de octubre de 2015).


La solución sugerida anteriormente para verificar el ANDROID_ID funcionó para mí hasta que actualice hoy las últimas herramientas SDK lanzadas con Android 2.2.

Por lo tanto, actualmente cambié a la siguiente solución que funciona hasta ahora con la desventaja, sin embargo, usted necesita poner el permiso de lectura PHONE_STATE ( <uses-permission android:name="android.permission.READ_PHONE_STATE"/> )

private void checkForDebugMode() { ISDEBUGMODE = false; //(Secure.getString(getApplicationContext().getContentResolver(), Secure.ANDROID_ID) == null); TelephonyManager man = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE); if(man != null){ String devId = man.getDeviceSoftwareVersion(); ISDEBUGMODE = (devId == null); } }


Los siguientes están configurados en "google_sdk":

Build.PRODUCT Build.MODEL

Por lo tanto, debería ser suficiente usar una de las siguientes líneas.

"google_sdk".equals(Build.MODEL)

o

"google_sdk".equals(Build.PRODUCT)


No sé si hay mejores formas de detectar el emu, pero el emulador tendrá el archivo init.goldfish.rc en el directorio raíz.

Es el script de inicio específico del emulador, y no debería estar allí en una compilación que no sea un emulador.


Nunca encontré una buena manera de saber si estás en el emulador.

pero si solo necesitas detectar si estás en un entorno de desarrollo, puedes hacer esto:

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

Espero que esto ayude....


Otra opción es verificar si está en modo de depuración o modo de producción:

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

Simple y confiable.

No es totalmente la respuesta a la pregunta, pero en la mayoría de los casos es posible que desee distinguir entre las sesiones de depuración / prueba y las sesiones de vida de su base de usuarios.

En mi caso, configuro Google Analytics como dryRun () cuando estoy en modo de depuración, por lo que este enfoque funciona perfectamente para mí.

Para usuarios más avanzados hay otra opción. Variantes de construcción de Gradle:

en el archivo gradle de su aplicación agregue una nueva variante:

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

En su código verifique el tipo de compilación:

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

Ahora tienes la oportunidad de construir 3 tipos diferentes de tu aplicación.


Otra opción sería mirar la propiedad ro.hardware y ver si está configurada para peces de colores. Desafortunadamente, no parece haber una forma fácil de hacer esto desde Java, pero es trivial desde C usando property_get() .


Poner un archivo en el sistema de archivos del emulador; Dado que el archivo no existirá en el dispositivo real, este debería ser estable, confiable y fácil de solucionar cuando se rompe.


Probé varias técnicas, pero me decidí por una versión ligeramente revisada de revisar el Build.PRODUCT como se muestra a continuación. Esto parece variar bastante de un emulador a otro, por eso tengo los 3 cheques que tengo actualmente. Supongo que podría haber comprobado si product.contains ("sdk") pero pensé que el cheque de abajo era un poco más seguro.

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

Para su información, encontré que mi Kindle Fire tenía Build.BRAND = "genérico", y algunos de los emuladores no tenían "Android" para el operador de red.


Solo busco _sdk , _sdk_ o sdk_ , o incluso simplemente sdk parte en Build.PRODUCT :

if(Build.PRODUCT.matches(".*_?sdk_?.*")){ //-- emulator -- }else{ //-- other device -- }


Todas las respuestas en un método.

Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")


Uno sems común para ser Build.FINGERPRINT.contains("generic")


puede consultar el IMEI #, http://developer.android.com/reference/android/telephony/TelephonyManager.html#getDeviceId%28%29

Si recuerdo en el emulador esta devolución 0. Sin embargo, no hay documentación que pueda encontrar que garantice eso. aunque es posible que el emulador no siempre devuelva 0, parece bastante seguro que un teléfono registrado no devolvería 0. Lo que sucedería en un dispositivo Android que no sea teléfono, o uno sin una tarjeta SIM instalada o uno que no esté registrado actualmente en el ¿red?

Parece que eso sería una mala idea, depender de eso.

También significa que necesitarás pedir permiso para leer el estado del teléfono, lo cual es malo si aún no lo necesitas para otra cosa.

si no es así, entonces siempre está cambiando algo de información antes de que finalmente genere su aplicación firmada.


usa esta función:

public static final boolean isEmulator() { int rating = 0; if ((Build.PRODUCT.equals("sdk")) || (Build.PRODUCT.equals("google_sdk")) || (Build.PRODUCT.equals("sdk_x86")) || (Build.PRODUCT.equals("vbox86p"))) { rating++; } if ((Build.MANUFACTURER.equals("unknown")) || (Build.MANUFACTURER.equals("Genymotion"))) { rating++; } if ((Build.BRAND.equals("generic")) || (Build.BRAND.equals("generic_x86"))) { rating++; } if ((Build.DEVICE.equals("generic")) || (Build.DEVICE.equals("generic_x86")) || (Build.DEVICE.equals("vbox86p"))) { rating++; } if ((Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk")) || (Build.MODEL.equals("Android SDK built for x86"))) { rating++; } if ((Build.HARDWARE.equals("goldfish")) || (Build.HARDWARE.equals("vbox86"))) { rating++; } if ((Build.FINGERPRINT.contains("generic/sdk/generic")) || (Build.FINGERPRINT.contains("generic_x86/sdk_x86/generic_x86")) || (Build.FINGERPRINT.contains("generic/google_sdk/generic")) || (Build.FINGERPRINT.contains("generic/vbox86p/vbox86p"))) { rating++; } return rating > 4; }


if ("sdk".equals( Build.PRODUCT )) { // Then you are running the app on the emulator. Log.w("MyAPP", "/n/n Emulator /n/n"); }


if (Build.BRAND.equalsIgnoreCase("generic")) { // Is the emulator }

Todas las referencias de BUILD son valores de build.prop, por lo que debe tener en cuenta que si va a poner esto en el código de lanzamiento, puede tener algunos usuarios con root que hayan modificado los suyos por cualquier motivo. Prácticamente no hay modificaciones que requieran el uso de genéricos como marca, a menos que se trate específicamente de emular el emulador.

Fingerprint es la compilación de compilación y la firma de compilación del kernel. Hay compilaciones que utilizan genéricos, generalmente de fuentes directamente de Google.

En un dispositivo que ha sido modificado, el IMEI también tiene la posibilidad de ser puesto a cero, por lo que no es confiable a menos que esté bloqueando por completo los dispositivos modificados.

Goldfish es la versión básica de Android de la que se extienden todos los demás dispositivos. CADA dispositivo Android tiene un init.goldfish.rc a menos que sea hackeado y eliminado por razones desconocidas.


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

Esto debería devolver verdadero si la aplicación se está ejecutando en un emulador.

Lo que debemos tener cuidado es no detectar todos los emuladores porque solo hay varios emuladores diferentes. Es fácil de comprobar. Tenemos que asegurarnos de que los dispositivos reales no se detecten como un emulador.

Utilicé la aplicación llamada " Compartir información de dispositivo Android " para verificar esto.

En esta aplicación, puede ver varios tipos de información de muchos dispositivos (probablemente la mayoría de los dispositivos en el mundo; si el dispositivo que está utilizando no se encuentra en la lista, se agregará automáticamente).