web-dev-qa-db-fra.com

Crashlytics (Fabric) organisations distinctes pour les variantes d'application (types de construction, variantes de produit)

Ceci est une question auto-répondue pour partager mes connaissances.

J'ai un projet avec plusieurs types de produits et je souhaite intégrer Fabric à l'aide d'organisations distinctes pour chaque type de produit.

J'ai essayé d'intégrer Fabric à l'aide d'Android Studio Fabric Plugin. Il ajoute 

<meta-data
    Android:name="io.fabric.ApiKey"
    Android:value="DEFAULT_ORGANIZATION_API_KEY" />

entrée dans AndroidManifest.xml de main ensemble de sources.

J'ai décidé de réécrire cette entrée dans des ensembles de sources spécifiques aux variantes d'application:

<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools">

    <application>
        <meta-data
            Android:name="io.fabric.ApiKey"
            Android:value="SECOND_ORGANIZATION_API_KEY"
            tools:replace="Android:value" />
    </application>
</manifest>

Ensuite, j'ai découvert que Fabric Gradle plug-in générait un fichier crashlytics.properties avec le secret de l'API de la structure (AKA Build Secret) lors de la construction et que je devrais inclure ce fichier dans le contrôle de source. Mais ce fichier est écrasé à chaque fois que je crée une variante d'application spécifique, car api secret est unique pour chaque application.

Comment puis-je intégrer Fabric en utilisant des organisations distinctes pour chaque variante d'application?

29
mixel

Pendant la construction, la tâche fabricGenerateResources est appelée et recherche un fichier nommé fabric.properties avec le contenu suivant:

apiSecret=YOUR_BUILD_SECRET
apiKey=YOUR_API_KEY

Donc tout ce dont nous avons besoin est de générer le fichier fabric.properties avant cela.

J'ai trouvé cette solution et l'a légèrement modifiée pour prendre en charge pleinement les variantes d'application, pas seulement les types de construction.

Ajoutez ce code à la section Android de build.gradle:

File crashlyticsProperties = new File("${project.projectDir.absolutePath}/fabric.properties")
applicationVariants.all { variant ->
    variant.productFlavors.each { flavor ->
        def variantSuffix = variant.name.capitalize()
        def generatePropertiesTask = task("fabricGenerateProperties${variantSuffix}") << {
            Properties properties = new Properties()
            properties.put("apiKey", flavor.fabricApiKey)
            properties.put("apiSecret", flavor.fabricApiSecret)
            properties.store(new FileWriter(crashlyticsProperties), "")
        }

        def generateResourcesTask = project.tasks.getByName("fabricGenerateResources${variantSuffix}")
        generateResourcesTask.dependsOn generatePropertiesTask
        generateResourcesTask.doLast {
            println "Removing fabric.properties"
            crashlyticsProperties.delete()
        }
    }
}

Il parcourt les variantes d'application et crée pour chaque variante d'application une tâche qui génère un fichier fabric.properties et une tâche qui supprime ce fichier après que le plug-in Fabric Gradle génère des ressources d'application.

Tout ce dont vous avez besoin maintenant, c’est de définir la saveur du produit ou le type de build spécifique fabricApiKey et fabricApiSecret:

productFlavors {
    flavor1 {
        ext.fabricApiKey = "FLAVOR1_API_KEY"
        ext.fabricApiSecret = "FLAVOR1_API_SECRET"
    }
}

ext est un ExtraPropertiesExtention object fourni par chaque ExtensionAware object. Il permet d'ajouter de nouvelles propriétés à un objet existant. Dans mon cas, flavor1 est un objet ExtensionAware et il peut être étendu avec de nouvelles propriétés à l'aide de la syntaxe ext.someProperty = "value". Plus tard, ces propriétés peuvent être utilisées comme flavor.someProperty, flavor.fabricApiKey.

De plus, il vaut mieux inclure fabric.properties à .gitignore.

Et n'oubliez pas de supprimer ext.enableCrashlytics = false du type de construction de débogage si vous l'avez utilisé pour désactiver Crashlytics lors du débogage. Au lieu de cela, vous pouvez le désactiver dans Application.onCreate:

Fabric.with(this, new Crashlytics.Builder().core(
    new CrashlyticsCore.Builder().disabled(BuildConfig.DEBUG).build()).build());
27
mixel

Si vous n'êtes pas opposé à l'utilisation d'un suffixe d'identification d'application, vous n'avez pas besoin d'organisations distinctes. Les accidents et les réponses seront traités comme des applications séparées.

Par exemple, disons que mon identifiant d'application est io.example

Dans votre build.gradle:

buildTypes {
  debug {
    applicationIdSuffix ".debug"
  }
  release {
    //options
  }
}

Après avoir déployé la version de débogage sur un périphérique ou un émulateur, vous verrez deux applications sur le site Fabric:

  • io.example
  • io.example.debug

Une bonne chose à propos de cette approche est que vous pouvez également suivre séparément les autres versions: io.exmaple.free, io.exmaple.paid, io.example.exterprise, etc.

5
Dave Jensen

Une solution plus simple, également compatible avec Gradle 5.x +, consiste à créer des fichiers fabric.properties distincts pour chacune des variantes de construction nécessitant une clé d’API Fabric unique et un secret. Créez les fichiers fabric.properties en tant que:

#Contains API Secret used to validate your application. Commit to internal source control; avoid making secret public.
apiSecret=YOUR_API_SECRET
apiKey=YOUR_API_KEY

en remplaçant YOUR_API_SECRET par le secret API de la variante de construction et YOUR_API_KEY par la clé API de la variante de construction.

Placez ensuite le fabric.properties de chaque variante dans le dossier du projet src/variant, par exemple. app/src/debug ou app/src/release. Voir la documentation sur les variantes de construction pour plus de détails.

Lors de la construction, le fabric.properties de la variante en cours de construction sera utilisé.

0
Jeff Lockhart