如何使用Gradle替换Google Maps API密钥?

6

为什么不能使用你链接的两个东西的组合?使用 credentials.whateverYouCallYourMapsApiKey 来填充 resValue - CommonsWare
你认为为不同的构建变体“release”和“debug”使用不同的字符串键可能不够吗? - shadowsheep
@shadowsheep 我不明白这样做如何将密钥存储在计算机中,避免将其发送到公共仓库? - Kheldar
如果你有一个名为api.keys的文件,其中包含你的密钥,并且你忽略它,那么这将是一个很好的解决方案,因此它不会被版本控制,只存在于你的电脑上。这样,在发布版本中获取生产密钥,在调试版本中获取开发密钥,这将是一个不错的选择。 - shadowsheep
啊,我知道你的意思了。我会试一下! - Kheldar
4个回答

11

您可以使用 manifestPlaceholders 将字符串从您的 build.gradle 注入。

  1. 将您的 API 密钥插入到像 local.properties 这样的文件中。
google.maps_api_key=SECRET_KEY
  1. 确保使用 .gitignore 忽略此文件:
local.properties
  1. 将API密钥提供给你的AndroidManifest.xml。使用withInputStream()确保InputStream自动关闭
android{
  defaultConfig {

    // Load credentials.
    def properties = new Properties()
    file("../local.properties").withInputStream { properties.load(it) }

    // Share the key with your `AndroidManifest.xml`
    manifestPlaceholders = [ googleMapsApiKey:"${properties.getProperty('google.maps_api_key')}"]
  1. 在你的AndroidManifest.xml中加载API密钥:
<application>

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${googleMapsApiKey}" />

有趣,下次遇到这种情况我会试试看! - Kheldar
2
谢谢!你的建议对我很有帮助!在找到它之前,我曾尝试使用 Google 在 https://developers.google.com/maps/documentation/android-sdk/get-api-key 上找到的建议,但它们没有起作用,因为它们没有提到“manifestPlaceholders”。 - porlicus
我使用gradle.properties来存储密钥,而不是使用local.properties。因为local.properties文件被排除在.gitignore中,这会给开发人员带来信息丢失的风险。请问我可以使用你的解决方案吗? - Abhinav Saxena
@AbhinavSaxena 应该可以工作,但这是有意的将 local.properties 从 git 中排除,因为通常不希望在存储库中存储敏感信息(这里是 Google Map Key)。即使您的存储库是私有的,您(或您的分支)可能会在某个时候将其设置为公共,然后其他人可以从 Git 历史记录中检索密钥。但这不是在此评论部分讨论的主题 :)。 - hb0
它成功了!(虽然以下内容与主题无关,但仍添加)local.properties文件为一台机器的Android和Native SDK路径。如果其他开发人员要在同一项目中进行贡献,则共享它是没有意义的。尽管Android Studio在项目启动时会自行更正错误路径,但仍然如此。谢谢。 :-) - Abhinav Saxena

4
您可以使用一个名为任意名称的非版本化文件,比如说api.keys,并将以下内容写入该文件:
debugMapsApiKey=xxxxXXXxxxx
releaseMapsApiKey=xxxYYYxxx

将它放在你的根项目文件夹中。

在你的build.gradle文件中,可以像这样读取该文件:

def apiKeysFile = rootProject.file("api.keys")
def apiKeysFile = new Properties()
apiKeysFile.load(new FileInputStream(apiKeysFile))

[...]

debug {
    buildConfigField "String", MAPS_KEY, apiKeysFile['debugMapsApiKey']
}

release {
    buildConfigField "String", MAPS_KEY, apiKeysFile['releaaseMapsApiKey']
}

你可以通过以下代码访问它:

BuildConfig.MAPS_KEY。如果你在调试中构建,值为"xxxxXXxxxx",而在发布中则为"xxxxYYxxxx"

如果你想在XML中访问它,可以使用resValue创建一个字符串资源。

debug {
    resValue "string", MAPS_KEY, apiKeysFile['debugMapsApiKey']
}

release {
   resValue "string", MAPS_KEY, apiKeysFile['releaseMapsApiKey']
}

通过这种方式,您也可以使用代码获取它

getString(R.string.MAPS_KEY)

嗯,它确实可以工作,但它并不完全符合我的要求,因为它忽略了我为其他键设置的工具。已点赞,但我会用另一种方式修复它们。 - Kheldar
@Kheldar 嗯,我不知道你为其他键设置了什么工具,但如果这个解决方案对你有所帮助,那么如果你愿意,你可以接受它作为正确答案。顺便说一句,这取决于你!我很高兴你完成了你的工作! ;) - shadowsheep
非常感谢,它确实帮助我缩小了我的推理范围 ^^ - Kheldar
错误:当前作用域已包含名称为apiKeysFile的变量 @第4行,第5列。 def apiKeysFile = new Properties() - Josef Vancura

1

google_maps_api.xml

<resources>
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">GoogleMapsApiKey</string>
</resources>

清单

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="@string/GoogleMapsApiKey"/>

gradle

resValue "string", "GoogleMapsApiKey", mapskey

gradle.properties

mapskey="AIza...8w" // key here

0

Shadowsheep的解决方案可行,但不是我想要做的。

最终我做了以下步骤:

  • 首先,我错误地认为必须使用密钥来填充google-maps-api.xml,而实际上在清单中设置密钥就足够了。

  • 其次,我在清单中添加了一行<meta-data android:name="com.google.android.geo.API_KEY" android:value"@string/GoogleMapsApiKey">

  • 第三,我通过我选择的工具(etiennestuder的gradle-credentials-plugin)设置了mapsKey。

  • 最后,我在应用程序模块的build.gradle buildTypes部分中添加了以下两行:

def mapsKey = credentials.GOOGLE_MAPS_API_KEY ?: "Key Missing"

it.resValue "string", "GoogleMapsApiKey", mapsKey


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接