Android build gradle - 替换字符串资源值

Ion*_*gru 2 string resources android replace gradle

我有一个特殊情况,我需要在使用Jenkins构建时覆盖谷歌地图键字符串变量.我已经设置了这样一个特殊的结构:

  • 调试
    • 水库
        • google_maps_api.xml
  • 主要
    • 水库
        • google_maps_api.xml

因此,在 res文件中我放了发布API密钥并在调试 res文件中我放了调试API密钥(对于我正在处理的机器 - 为Android的debug.keystore生成).

在构建gradle文件中,我有这个基本逻辑,用于根据Jenkins环境中的设置创建字符串资源:

String googleMapApiKey = System.env.MAP_API_KEY;
...
android {
    ...
    buildTypes {
        ...
        debug {
             if (null != googleMapApiKey && !googleMapApiKey.equals("null")) {
                resValue "string", "google_maps_key", googleMapApiKey
            }
        }
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

xml文件包含:

<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
    MY_DEBUG_API_KEY
</string>
Run Code Online (Sandbox Code Playgroud)

我知道问题是因为字符串资源的保留标志,但如果删除,有可能事情搞砸了并且松散了字符串资源.有没有办法可以替换实际字符串资源的值而不只是在构建gradle文件中创建一个新的?

我只是认为当我使用Jenkins环境中的值时,解决方案也可以排除该文件,但我不知道它是否适用于android gradle系统.有谁知道这是否可行而且更重要,如何?

LE:

看来我有到RES文件从移动文件夹到版本之一.因此我现在有以下结构:

  • 调试
    • 水库
        • google_maps_api.xml
  • 发布
    • 水库
        • google_maps_api.xml

现在,似乎这样工作.

LLE: 上面的方法不起作用,我的结论很快.似乎仍然使用xml文件中的值,即使我在gradle脚本中声明了相同的内容(至少作为名称).

Ion*_*gru 5

作为解决方法,我实现了以下逻辑:

  • google_maps_api.xml发布文件夹中删除了
  • 我创建了一个自定义方法,从local.properties加载属性:

    /**
     * Get Google Map API Key which should be used by google map services.
     * <br/>
     * Note that this key should not be used when an key is available from Jenkins as most probably debug.keystore is
     * different than the one on your machine.
     *
     * @return the value of your local Google Map API Key
     */
    def getLocalGoogleMapApiKey() {
        Properties properties = new Properties()
        properties.load(project.rootProject.file('local.properties').newDataInputStream())
        def localMalKey = properties.getProperty('google.map.apiKey')
        if (localMalKey == null) {
            // Throw an exception if the property wasn't setup for this
            throw new GradleException(
                    "Google Map API Key property not found. Define your debug Google Map API Key [google.map.apiKey] in " +
                            "your local.properties file! E.g.: google.map.apiKey=YOUR_GOOGLE_MAP_API_KEY")
        }
    
        return localMalKey
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 我在local.properties文件中添加了以下属性

    google.map.apiKey=MY_API_KEY
    
    Run Code Online (Sandbox Code Playgroud)
  • 我在build.gradle中添加了以下逻辑:

    ...
    // Google Map API Key - from Jenkins or from local
    String googleMapApiKey = System.env.MAP_API_KEY ?: getLocalGoogleMapApiKey();
    ...
    android {
        ...
        buildTypes {
            ...
            debug {
                /* Create a string resource which will be used in AndroidManifest.xml file (from Jenkins or local)*/
                resValue "string", "google_maps_key", googleMapApiKey
                println(">>>>>>>>> Google Map API Key: " + googleMapApiKey)
            }
            ...
        }
        ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

我选择了这个解决方案,原因如下:

  • 每个用户都可以设置自己的API KEY进行调试(local.properties文件不会影响其他开发人员,因为它永远不会进入存储库)
  • Jenkins可以在不影响项目或任何开发人员的情况下随时更改密钥
  • 没有必要改变项目的结构或乱用它的资源
  • 任何人都可以安全使用该方法,如果有人没有正确设置属性,它会抛出一个很好的错误

我希望这有助于其他有类似问题的人: