Crashlytics发现了一个无效的API密钥

时间:2014-09-06 13:17:32

标签: android gradle android-studio android-gradle crashlytics

当我尝试使用value meta-data标记作为字符串引用构建项目时,崩解失败并出现以下错误:

Crashlytics found an invalid API key: @string/crashlytics. 
Check the Crashlytics plugin to make sure that the application has been added successfully! 
Contact support@crashlytics.com for assistance.

不起作用

<meta-data
    android:name="com.crashlytics.ApiKey"
    android:value="@string/crashlytics"/>

作品

<meta-data
    android:name="com.crashlytics.ApiKey"
    android:value="1234567890..."/>

我想在string.xml内为我的android项目的不同productFlavors定义不同的键。

更新

写完崩溃支持后:

  

目前我们只能在构建时评估AndroidManifest.xml,因此我们不会查看任何字符串资源,因此我们只支持硬编码字符串。我肯定会与你感兴趣的团队分享这个,所以我们可以在将来的版本中考虑支持这个。

2 个答案:

答案 0 :(得分:51)

  

修改:只有当您使用Crashlytics的旧版本时(我使用的是v1.1.11),才能使用已接受的解决方案。如果您使用的是Fabric SDK,您会注意到   插件的任务已经发生了很大变化,下面的脚本也是如此   不管用。因此,不再需要API秘密   您可以使用清单中的<meta>来指定API密钥以及在您的风格中定义的清单占位符:

     
       build.gradle

    中的
  •      

    flavor1 {
        ...
        manifestPlaceholders = [crashlyticsApiKey: CRASHLYTICS_API_SECRET_HERE]
        ...
    }
    
      
  •    AndroidManifest.xml 中的
  •      
    ...
    <meta-data
        android:name="com.crashlytics.ApiKey"
        android:value="${crashlyticsApiKey}" />
    ...
    
      
  •   

还有另一种未记录的方法将Crashlytics键指定为noted here,并使用crashlytics.properties(在项目的根目录中)指定该值以及API密钥:< / p>

apiKey=YOUR_API_KEY
apiSecret=YOUR_API_SECRET

不幸的是,这不允许您为每种风格简单地指定不同的crashlytics.properties,因为它需要位于项目的根目录中才能被gradle插件正确选取。这意味着您需要动态生成该文件。 我们的想法是将您的风格中的键/密钥值添加为自定义属性,并在构建时生成crashlytics.properties,使用当前风味中的值来填充文件。

你的android模块里面的build.gradle应该是这样的:

...
productFlavors {

    flavor1 {
        ...
        set("crashlyticsApiKey", CRASHLYTICS_API_KEY_HERE)
        set("crashlyticsApiSecret", CRASHLYTICS_API_SECRET_HERE)
        ...
    }
    ...
}

File crashlyticsProperties = new File("${project.projectDir.absolutePath}/crashlytics.properties")
applicationVariants.all { variant ->
    variant.productFlavors.each { flavor ->
        def variantSuffix = variant.name.capitalize()
        def generateResourcesTask = project.tasks.getByName("crashlyticsGenerateResources${variantSuffix}")
        def generatePropertiesTask = task("crashlyticsGenerateProperties${variantSuffix}") << {
            Properties properties = new Properties()
            println "...copying apiSecret for ${variant.name}"
            properties.put("apiSecret", flavor.crashlyticsApiSecret)
            println "...copying apiKey for ${variant.name}"
            properties.put("apiKey", flavor.crashlyticsApiKey)
            properties.store(new FileWriter(crashlyticsProperties), "")
        }
        generateResourcesTask.dependsOn generatePropertiesTask
        def cleanResourcesTask = project.tasks.getByName("crashlyticsCleanupResourcesAfterUpload${variantSuffix}")
        cleanResourcesTask.doLast {
            println "...removing crashlytics.properties"
            crashlyticsProperties.delete()
        }
    }
}
...

基本上,脚本会在构建过程中挂钩,并在Crashlytics gradle插件发挥其魔力之前生成/填充属性文件。

答案 1 :(得分:0)

使用Fabric&#39的Crashlytics 2.6.6。我可以从菜单中选择Build Variant(通常位于Android Studio的左侧)并运行应用程序。传播到Fabric仪表板需要一分钟左右,但我没有任何需要解决方法。