2009-11-16 13 views
52

Je crée une application Android et souhaite conserver quelques variables d'environnement que je peux modifier selon que je suis en mode développement ou en mode édition. Par exemple, je dois appeler un service Web et l'URL sera légèrement différente dans les deux modes. Je voudrais externaliser ce paramètre et d'autres afin que je puisse les changer facilement en fonction de mon déploiement cible.Distinguer le mode de développement et les paramètres d'environnement du mode de publication sur Android

Existe-t-il des meilleures pratiques ou quoi que ce soit dans le SDK pour répondre à ce besoin?

Répondre

28

Selon cette stackoverflow post, dans SDK Tools version 17 (nous sommes le 19 de cette écriture) ajoute une constante BuildConfig.DEBUG qui est vrai lors de la construction d'une construction dev.

+2

Marquer cela comme la réponse acceptée maintenant, car il sera probablement plus applicable aux futurs voyageurs –

+0

Fonctionne pour moi dans ** API 15 **, 4.0.3. –

+1

API n'a pas d'importance, juste la version des outils de construction. – yincrash

3

Je vérifierais isDebuggerConnected

+1

Merci, ce peut être utile un jour, mais je peux techniquement exécuter la émulateur en mode développement avec un débogueur joint. –

43

La solution suivante suppose que dans le fichier manifeste toujours définir android:debuggable=true tout en développant et android:debuggable=false pour la libération de l'application.

Maintenant, vous pouvez vérifier la valeur de cet attribut à partir de votre code en vérifiant le drapeau ApplicationInfo.FLAG_DEBUGGABLE dans le ApplicationInfo obtenu à partir de PackageManager.

Le code suivant pourrait aider:

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

Depuis les versions les plus récentes du SDK, cela semble être la meilleure approche, car Eclipse et Ant le définissent automatiquement en fonction du type de construction. – Zulaxia

3

Que diriez-vous quelque chose comme le code ci-dessous ...

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

Le DEBUGKEY dans ce cas est en fait le certificat entier. Je recommande d'utiliser la méthode dans http://stackoverflow.com/questions/6122401/android-compare-signature-of-current-package-with-debug-keystore à la place. De cette façon, vous n'êtes pas limité à la clé de débogage d'une seule machine. – Ralf

1

je suis tombé sur une autre approche aujourd'hui par hasard qui semble vraiment en avant droit .. Regardez Build.TAGS, lorsque l'application est créée pour le développement de cette évalue à la chaîne "test-keys".

Ne devient pas beaucoup plus facile qu'une comparaison de chaîne.

Aussi Build.MODEL et Build.PRODUCT évaluent à la chaîne "google_sdk" sur l'émulateur!

+0

Est-ce fiable? Il semble que les clés de test peuvent être définies pour les périphériques enracinés: http://stackoverflow.com/questions/1101380/determine-if-running-on-a-rooted-device Cela me fait penser qu'il peut y avoir d'autres cas où cette approche pourrait échouer. – christoff

+0

Non, ce n'est pas fiable. – shkschneider

9

@ viktor-bresan Merci pour une solution utile. Il serait plus utile si vous avez simplement inclus une manière générale de récupérer le contexte de l'application en cours pour en faire un exemple complet. Quelque chose le long des lignes du ci-dessous:

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

Android build.gradle dispose d'un environnement de débogage et de libération des poignées.

Append l'extrait de code suivant dans build.gradle fichier

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

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

Maintenant, vous pouvez accéder à la variable comme ci-dessous

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