2009-11-16 15 views
52

Estoy creando una aplicación de Android y me gustaría mantener algunas variables de entorno que puedo modificar dependiendo de si estoy en modo de desarrollo o de lanzamiento. Por ejemplo, necesito invocar un servicio web y la URL será ligeramente diferente en cualquier modo. Me gustaría externalizar esta y otras configuraciones para poder cambiarlas fácilmente en función de mi implementación de destino.Distinguir el modo de desarrollo y la configuración del entorno del modo de lanzamiento en Android

¿Existen mejores prácticas o algo en el SDK para ayudar con esta necesidad?

Respuesta

28

De acuerdo con este stackoverflow post, en Herramientas del SDK versión 17 (somos el 19 de este escrito) se suma una constante BuildConfig.DEBUG que es cierto en la construcción de una acumulación prog.

+2

Marcando esto como la respuesta aceptada ahora porque probablemente sea más aplicable a futuros viajeros –

+0

Funciona para mí en ** API 15 **, 4.0.3. –

+1

API no importa, solo la versión de herramientas de compilación. – yincrash

3

Me volvería a la salida isDebuggerConnected

+1

Gracias, que pueden venir bien un día, pero técnicamente se puede ejecutar el emulador en modo de desarrollo sin depurador adjunto. –

43

La siguiente solución asume que en el archivo de manifiesto siempre establezca android:debuggable=true mientras que el desarrollo y android:debuggable=false para el lanzamiento de la aplicación.

Ahora puede verificar el valor de este atributo desde su código marcando ApplicationInfo.FLAG_DEBUGGABLE en el ApplicationInfo obtenido de PackageManager.

El siguiente fragmento de código podría ayudar:

PackageInfo packageInfo = ... // get package info for your context 
int flags = packageInfo.applicationInfo.flags; 
if ((flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 
    // development mode 
} else { 
    // release mode 
} 
+4

A partir de las versiones SDK más recientes, este parece ser el mejor enfoque, ya que tanto Eclipse como Ant configuran esto automáticamente dependiendo del tipo de compilación. – Zulaxia

3

¿Qué tal algo así como el código de abajo ...

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; 

} 
+0

El DEBUGKEY en este caso es en realidad el certificado completo. Recomiendo usar el método en http://stackoverflow.com/questions/6122401/android-compare-signature-of-current-package-with-debug-keystore en su lugar. De esta manera, no está limitado a la clave de depuración de una sola máquina. – Ralf

1

me encontré con otro enfoque hoy por accidente que parece muy sencillo .. Mira Build.TAGS, cuando se crea la aplicación para el desarrollo de este evalúa a la cadena de "claves de prueba".

No es mucho más fácil que comparar una cadena.

¡También Build.MODEL y Build.PRODUCT evalúan a la cadena "google_sdk" en el emulador!

+0

¿Es esto confiable? Parece que las claves de prueba se pueden configurar para dispositivos rooteados: http://stackoverflow.com/questions/1101380/determine-if-running-on-a-rooted-device Eso me hace pensar que puede haber otros casos donde este enfoque podría fallar – christoff

+0

No, esto no es confiable. – shkschneider

9

@ viktor-bresan Gracias por una solución útil. Sería más útil si solo incluyeras una forma general de recuperar el contexto de la aplicación actual para que sea un ejemplo totalmente funcional. Algo a lo largo de las líneas de los siguientes:

PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); 
2

Android build.gradle maneja bien el entorno de depuración y liberación.

anexar el siguiente fragmento de código en build.gradle archivo

buildTypes { 
    debug { 
     buildConfigField "Boolean", "IS_DEBUG_MODE", 'true' 
    } 

    release { 
     buildConfigField "Boolean", "IS_DEBUG_MODE", 'false' 
    } 
} 

Ahora se puede acceder a la variable, como a continuación

if (BuildConfig.IS_DEBUG_MODE) { { 
     //Debug mode. 
    } else { 
     //Release mode 
    } 
Cuestiones relacionadas