Utiliser Crashlytics dans une version de produit dans Android Studio

J’utilise Android Studio pour développer mon application et utiliser gradle en créant quelques produits. Les saveurs du produit sont google, beta et lab.

Je veux seulement intégrer Crashlytics avec un seul produit ( version bêta ), mais je suis confronté à un problème que je n’ai pas pu résoudre.

Avec le fichier build.gradle actuel, je peux comstackr les variantes de compilation betaDebug et betaRelease, mais je ne parviens pas à comstackr les autres.

De plus, je n’ai pas réussi à convaincre Crashlytics de reconnaître mon application après avoir lancé avec succès la variante de construction betaDebug.

L’erreur que j’obtiens lorsque je passe à une variante de construction différente:

Gradle Running Failed to complete Gradle exection. Cause: Could not execute build using Gradle dissortingbution 'http://services.gradle.org/dissortingbutions/gradle-1.10-all.zip'. 

Voici mon fichier build.gradle:

 buildscript { repositories { maven { url 'http://download.crashlytics.com/maven' } } dependencies { classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+' } } apply plugin: 'android' apply plugin: 'crashlytics' repositories { maven { url 'http://download.crashlytics.com/maven' } } android { comstackSdkVersion 19 buildToolsVersion "19.0.1" defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" packageName "com.mcarrano.example" } buildTypes { debug { packageNameSuffix '.debug' versionNameSuffix '-DEBUG' } release { runProguard true debuggable false proguardFile 'proguard-rules.txt' proguardFile getDefaultProguardFile('proguard-android-optimize.txt') } } productFlavors { google { packageName = android.defaultConfig.packageName versionName = android.defaultConfig.versionName } beta { packageName = android.defaultConfig.packageName + ".beta" versionName = android.defaultConfig.versionName + "-BETA" } lab { packageName = android.defaultConfig.packageName + ".lab" versionName = android.defaultConfig.versionName + "-LAB" } } sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java'] res.srcDirs = ['src/main/res'] assets.srcDirs = ['src/main/assets'] } google { java.srcDirs = ['src/google/java'] } beta { manifest.srcFile 'src/beta/AndroidManifest.xml' java.srcDirs = ['src/beta/java'] } lab { java.srcDirs = ['src/lab/java'] } } } dependencies { comstack 'com.android.support:support-v4:19.0.+' comstack 'com.android.support:appcompat-v7:19.0.+' betaComstack 'com.crashlytics.android:crashlytics:1.+' } 

Voici la console Gradle lorsque l’application ne parvient pas à comstackr:

 Executing tasks: [:example:generateGoogleDebugSources] Relying on packaging to define the extension of the main artifact has been deprecated and is scheduled to be removed in Gradle 2.0 :example:preBuild :example:preGoogleDebugBuild :example:checkGoogleDebugManifest :example:preBetaDebugBuild :example:preBetaReleaseBuild :example:preGoogleReleaseBuild :example:preLabDebugBuild :example:preLabReleaseBuild :example:prepareComAndroidSupportAppcompatV71901Library UP-TO-DATE :example:prepareGoogleDebugDependencies :example:comstackGoogleDebugAidl UP-TO-DATE :example:comstackGoogleDebugRenderscript UP-TO-DATE :example:generateGoogleDebugBuildConfig UP-TO-DATE :example:processGoogleDebugManifest UP-TO-DATE :example:crashlyticsCleanupResourcesGoogleDebug ERROR - Crashlytics Developer Tools error. java.lang.IllegalArgumentException: Invalid API key: null. Check the Crashlytics plugin to make sure that the application has been added successfully! Contact [email protected] for assistance. at com.crashlytics.tools.android.DeveloperTools.processProperties(DeveloperTools.java:439) at com.crashlytics.tools.android.DeveloperTools.processArgs(DeveloperTools.java:325) at com.crashlytics.tools.android.DeveloperTools.main(DeveloperTools.java:285) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.invoke(StaticMetaMethodSite.java:43) at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.call(StaticMetaMethodSite.java:88) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) at com.crashlytics.tools.gradle.CrashlyticsTaskBuilder.callDevtoolsWrappingRuntimeExceptions(CrashlyticsTaskBuilder.groovy:136) at com.crashlytics.tools.gradle.CrashlyticsTaskBuilder.this$2$callDevtoolsWrappingRuntimeExceptions(CrashlyticsTaskBuilder.groovy) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:361) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:877) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:46) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141) at com.crashlytics.tools.gradle.CrashlyticsTaskBuilder$_crashlyticsCleanupResources_closure2.doCall(CrashlyticsTaskBuilder.groovy:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:877) at groovy.lang.Closure.call(Closure.java:412) at groovy.lang.Closure.call(Closure.java:425) at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:502) at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:483) at org.gradle.api.internal.tasks.TaskStatusNagger$1.execute(TaskStatusNagger.java:77) at org.gradle.api.internal.tasks.TaskStatusNagger$1.execute(TaskStatusNagger.java:73) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61) at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46) at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35) at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:64) at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58) at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:42) at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52) at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53) at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43) at org.gradle.api.internal.AbstractTask.executeWithoutThrowingTaskFailure(AbstractTask.java:289) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.executeTask(AbstractTaskPlanExecutor.java:79) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:63) at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:51) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$1.run(DefaultTaskPlanExecutor.java:33) at org.gradle.internal.Factories$1.create(Factories.java:22) at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:198) at org.gradle.cache.internal.DefaultCacheAccess.longRunningOperation(DefaultCacheAccess.java:266) at org.gradle.cache.internal.DefaultPersistentDirectoryStore.longRunningOperation(DefaultPersistentDirectoryStore.java:135) at org.gradle.api.internal.changedetection.state.DefaultTaskArtifactStateCacheAccess.longRunningOperation(DefaultTaskArtifactStateCacheAccess.java:95) at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:31) at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:86) at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:29) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61) at org.gradle.execution.DefaultBuildExecuter.access$200(DefaultBuildExecuter.java:23) at org.gradle.execution.DefaultBuildExecuter$2.proceed(DefaultBuildExecuter.java:67) at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:61) at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:54) at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:166) at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:113) at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:81) at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:64) at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:70) at org.gradle.tooling.internal.provider.BuildModelAction.run(BuildModelAction.java:30) at org.gradle.tooling.internal.provider.ConfiguringBuildAction.run(ConfiguringBuildAction.java:108) at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:35) at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:45) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:42) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:71) at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:69) at org.gradle.util.Swapper.swap(Swapper.java:38) at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:69) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:60) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:45) at org.gradle.launcher.daemon.server.DaemonStateCoordinator.runCommand(DaemonStateCoordinator.java:186) at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49) at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:36) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.DaemonHygieneAction.execute(DaemonHygieneAction.java:39) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32) at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125) at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:51) at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.handleCommand(DefaultIncomingConnectionHandler.java:155) at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.receiveAndHandleCommand(DefaultIncomingConnectionHandler.java:128) at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.run(DefaultIncomingConnectionHandler.java:116) at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918) at java.lang.Thread.run(Thread.java:695) usage: com.crashlytics.tools.android.DeveloperTools -androidManifest  Path to AndroidManifest.xml) -androidRes  Path to Android resources (res/ folder) -apiSecret  API Secret for the project -buildEvent Notify Crashlytics that a build event has occurred -cleanupResourceFile Remove Crashlytics-generated resource files -generateResourceFile Generate Crashlytics-required resources for the project. -help Display command help. -obfuscator  Optionally specify an obfuscator vendor identifier for use with storeDeobs. -obVer  Optionally specify the obfuscator vendor software version for use with obfuscator. -projectPath  Path to Android project root -properties  Properties file that overrides the input properties -quiet Silent command line output -requireUploadSuccess Throw an exception if the deobfuscation upload was not successful -resourceCheck Check if a resource file already exists. -storeDeobs  Store the specified deobfuscation file in preparation for upload. -tool  Name of the build tool -uploadDeobs Attempt to upload deobfuscation file(s) to Crashlytics servers. -uploadDist  -verbose Verbose command line output -version  Version of the build tool 

A eu un problème similaire: j’ai dû désactiver les rapports de crashlytics dans les versions de débogage. La réponse de Michael ne m’a pas aidé: crashlytics a détruit l’application au démarrage après avoir ajouté ext.enableCrashlytics = false pour graduer la configuration. Grâce à Github, j’ai trouvé une solution de travail:

build.gradle:

 //... android { buildTypes { debug { // enable crashlytics where you need buildConfigField "boolean", "USE_CRASHLYTICS", "false" ext.enableCrashlytics = false } } } // ... 

et classe d’application :

 @Override public void onCreate() { //... if ( BuildConfig.USE_CRASHLYTICS ) { Crashlytics.start(this); } //... } 

MODIFIER

Selon le commentaire de slott : avec le Fabric, vous devriez utiliser quelque chose comme ceci:

 Fabric.with(this, new Crashlytics.Builder().core(new CrashlyticsCore.Builder().disabled(!BuildConfig.USE_CRASHLYTICS).build()).build()); 

Merci beaucoup à @bonnell pour avoir répondu à ma question par email.

Ajoutez simplement ext.enableCrashlytics = false à toute version / saveur dont vous ne voulez pas que Crashlytics fasse partie.

Pour une réponse complète qui résout mon problème:

 buildscript { repositories { maven { url 'http://download.crashlytics.com/maven' } } dependencies { classpath 'com.crashlytics.tools.gradle:crashlytics-gradle:1.+' } } apply plugin: 'android' apply plugin: 'crashlytics' repositories { maven { url 'http://download.crashlytics.com/maven' } } android { comstackSdkVersion 19 buildToolsVersion "19.0.1" defaultConfig { minSdkVersion 8 targetSdkVersion 19 versionCode 1 versionName "1.0" packageName "com.mcarrano.example" } buildTypes { debug { packageNameSuffix '.debug' versionNameSuffix '-DEBUG' } release { runProguard true debuggable false proguardFile 'proguard-rules.txt' proguardFile getDefaultProguardFile('proguard-android-optimize.txt') } } productFlavors { google { packageName = android.defaultConfig.packageName versionName = android.defaultConfig.versionName ext.enableCrashlytics = false } beta { packageName = android.defaultConfig.packageName + ".beta" versionName = android.defaultConfig.versionName + "-BETA" } lab { packageName = android.defaultConfig.packageName + ".lab" versionName = android.defaultConfig.versionName + "-LAB" ext.enableCrashlytics = false } } sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java'] res.srcDirs = ['src/main/res'] assets.srcDirs = ['src/main/assets'] } google { java.srcDirs = ['src/google/java'] } beta { manifest.srcFile 'src/beta/AndroidManifest.xml' java.srcDirs = ['src/beta/java'] } lab { java.srcDirs = ['src/lab/java'] } } } dependencies { comstack 'com.android.support:support-v4:19.0.+' comstack 'com.android.support:appcompat-v7:19.0.+' betaComstack 'com.crashlytics.android:crashlytics:1.+' } 

Pour quiconque ayant ce problème, mon problème était que la clé Crashlytics n’était pas définie dans mon fichier AndroidManifest.xml, par exemple:

         

Si je veux partager la construction via crashlytics.

J’ai besoin d’installer le plugin Fabric et de m’inscrire après ça ..

**

debug {ext.enableCrashlytics = true}

**

après la construction de l’application, nous pouvons facilement partager via crashlytics

Merci

pour arrêter crashlytics pour les versions de débogage, j’ai ajouté le code ci-dessous après le code d’initialisation dans la première activité (de démarrage)

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