40 votes

Android : choisir automatiquement la clé d'api debug/release Maps ?

OBSOLETED : cette ancienne question fait référence à l'API v1 de Google Maps, qui est obsolète. Lorsque vous utilisez l'API v2, vous pouvez utiliser plusieurs empreintes de certificat dans une même Google API Console entrée. La clé API n'est plus stockée dans le manifeste ni dans le code.


Est-il possible de détecter automatiquement quel certificat a été utilisé pour signer l'APK ? J'aimerais avoir à la fois les certificats de débogage et de libération de Maps dans l'application et passer le certificat valide au constructeur de MapView.

Avec une telle configuration, je ne ferai pas d'erreur lors de la publication de l'application - j'utilise le certificat de débogage sur l'émulateur et mon appareil, puis je signe avec le certificat de publication avant d'envoyer l'application sur le marché.

Je pensais détecter mon appareil particulier ou si le débogueur est connecté mais ce n'est pas parfait. Peut-être qu'un marquage de fichier est nécessaire pour le certificat de débogage ? Existe-t-il une meilleure solution ?

47voto

Alexander Mironov Points 704

Il y a une nouvelle façon de déterminer s'il s'agit d'une version de débogage ou d'une version de publication dans Outils SDK, Révision 17 . Un extrait de l'aperçu des nouvelles fonctionnalités :

Les constructions génèrent maintenant une classe appelée BuildConfig contenant un DEBUG constante qui est automatiquement définie en fonction de votre type de construction. Vous pouvez vérifier la ( BuildConfig.DEBUG ) dans votre code pour exécuter les fonctions de débogage uniquement.

Vous pouvez donc maintenant écrire simplement quelque chose comme ceci :

if (BuildConfig.DEBUG)
{
    //Your debug code goes here
}
else
{
    //Your release code goes here
}

UPDATE : J'ai rencontré un bug dans ADT : parfois BuildConfig.DEBUG es true après avoir exporté le dossier de candidature. La description est ici : http://code.google.com/p/Android/issues/detail?id=27940

26voto

Bachi Points 2009

J'ai eu le même problème avec la clé API. Voici une solution complète, basée sur le lien ci-dessus et sur les éléments suivants exemple de Bijarni (qui d'une manière ou d'une autre n'a pas fonctionné pour moi), j'utilise maintenant cette méthode :

// Define the debug signature hash (Android default debug cert). Code from sigs[i].hashCode()
protected final static int DEBUG_SIGNATURE_HASH = <your hash value>;

// Checks if this apk was built using the debug certificate
// Used e.g. for Google Maps API key determination (from: http://whereblogger.klaki.net/2009/10/choosing-android-maps-api-key-at-run.html)
public static Boolean isDebugBuild(Context context) {
    if (_isDebugBuild == null) {
        try {
            _isDebugBuild = false;
            Signature [] sigs = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;
            for (int i = 0; i < sigs.length; i++) {
                if (sigs[i].hashCode() == DEBUG_SIGNATURE_HASH) {
                    Log.d(TAG, "This is a debug build!");
                    _isDebugBuild = true;
                    break;
                }
            }
        } catch (NameNotFoundException e) {
            e.printStackTrace();
        }      
    }
    return _isDebugBuild;
}

Vous devez trouver le hashValue() de votre signature de débogage une fois, il suffit de sortir sigs[i].hashCode().

Ensuite, je ne voulais pas ajouter dynamiquement le MapView, mais plutôt utiliser le fichier xml. Vous ne pouvez pas définir l'attribut api key dans le code et utiliser un layout xml, donc j'utilise cette méthode simple (bien que copier le layout xml ne soit pas si beau) :

Dans mon MapActivity :

    public void onCreate(Bundle savedInstanceState)
    {       
    super.onCreate(savedInstanceState);

    // Select the proper xml layout file which includes the matching Google API Key
    if (isDebugBuild(this)) {
        setContentView(R.layout.map_activity_debug);
    } else {
        setContentView(R.layout.map_activity_release);
    }

10voto

Suriya Points 166

Le moyen le plus simple de déterminer s'il s'agit d'un build de débogage est de vérifier le drapeau de débogage sur l'info de l'application plutôt que le hachage de la signature.

public boolean isDebugBuild() throws Exception
{
   PackageManager pm = _context.getPackageManager();
   PackageInfo pi = pm.getPackageInfo(_context.getPackageName(), 0);

   return ((pi.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}

Une fois la version de débogage trouvée, vous pouvez soit utiliser une ressource différente pour afficher la carte, soit créer la vue de la carte dans l'application et l'ajouter à une mise en page.

    if(isDebugBuild())
    {
        _mapView = new MapView(this, getString(R.string.debugmapskey));
    }
    else
    {
        _mapView = new MapView(this, getString(R.string.releasemapskey));
    }

3voto

ge0rg Points 984

J'ai contourné l'horrible mauvaise intégration des clés d'api dans le processus de construction et le contrôle de la source en en faisant une propriété stockée dans le fichier local.properties . J'ai dû ajouter ce qui suit à build.xml :

<property name="mapviewxml" value="res/layout/mapview.xml" />
<target name="-pre-build">
    <fail unless="mapsApiKey">You need to add mapsApiKey=... to local.properties</fail>
    <copy file="mapview.xml.tpl" tofile="${mapviewxml}" overwrite="true">
        <filterchain>
            <replacetokens>
                <token key="apiKey" value="${mapsApiKey}"/>
            </replacetokens>
        </filterchain>

    </copy>
</target>

Maintenant, bien sûr, je devais créer mapview.xml.tpl dans la Racine de mes projets (il ne peut pas aller à res/layout car cela briserait le processus de construction) :

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.maps.MapView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mapview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
    android:apiKey="@apiKey@"
    />

Pendant la précompilation, le modèle est copié au bon endroit et @apiKey@ est remplacé par la vraie clé. Malheureusement, je n'ai pas trouvé de moyen de distinguer les builds debug et release dans cette phase, donc pour compiler pour la release, j'ajoute simplement l'apiKey release aux paramètres ant :

ant -DmapsApiKey=.... release 

Cette approche s'intègre bien avec SCM (je n'ai pas besoin de vérifier les clés) et de manière acceptable avec le processus de construction.

3voto

Gromix Points 1443

Si vous êtes toujours intéressé, je viens de publier un blog sur une autre façon de procéder. Avec une simple modification du build script d'Android, vous pouvez changer la clé API de la carte ainsi que tous les autres changements de version nécessaires. Ce que j'aime dans cette méthode, c'est que rien de ce qui est lié au débogage n'est intégré à la version, et que vous pouvez conserver les mises en page XML telles qu'elles étaient auparavant.

http://blog.cuttleworks.com/2011/02/Android-dev-prod-builds/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X