Android build gradle - 替换字符串资源值
Android build gradle - replace string resource value
我有一个特殊情况,在使用 Jenkins 构建时我需要覆盖 google 映射键字符串变量。我设置了一个像这样的特殊结构:
- debug
- res
- value
- google_maps_api.xml
- main
- res
- value
- google_maps_api.xml
因此,在 main res 文件中我放入了 release API 键,在 debug 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
}
}
...
}
...
}
xml 文件包含:
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
MY_DEBUG_API_KEY
</string>
我知道问题出在字符串资源的保留标志上,但如果删除它,可能会搞砸并丢失该字符串资源。
有没有一种方法可以替换实际字符串资源的值,而不是仅仅在构建 gradle 文件中创建一个新字符串?
我只是想一个解决方案也可以是在我使用 Jenkins 环境中的值时排除该文件,但我不知道 android gradle 是否可行系统。有谁知道这是否可行并且更重要,怎么做?
LE:
看来我必须将 res 文件从 main 文件夹移动到 release 文件夹中。因此我现在有以下结构:
- debug
- res
- value
- google_maps_api.xml
- release
- res
- value
- google_maps_api.xml
目前,它似乎是这样工作的。
LLE:
上面的方法行不通,我很快就得出了结论。 xml 文件中的值似乎仍在使用,即使我在 gradle 脚本中声明相同(至少作为名称)也是如此。
作为解决此问题的方法,我实现了以下逻辑:
- 我从 release 文件夹中删除了
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
}
我在local.properties文件
中添加了以下属性
google.map.apiKey=MY_API_KEY
我在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)
}
...
}
...
}
我选择了这个解决方案,原因如下:
- 每个用户都可以设置自己的 API KEY 用于调试(local.properties 文件不会影响其他开发人员,因为它永远不会进入存储库)
- Jenkins 可以随时更改它的密钥,而不会影响项目或任何开发人员
- 不需要改变项目的结构或乱用它的资源
- 任何人都可以安全地使用该方法,如果有人没有正确设置 属性,它会抛出一个很好的错误
我希望这能帮助其他有类似问题的人:
我有一个特殊情况,在使用 Jenkins 构建时我需要覆盖 google 映射键字符串变量。我设置了一个像这样的特殊结构:
- debug
- res
- value
- google_maps_api.xml
- main
- res
- value
- google_maps_api.xml
因此,在 main res 文件中我放入了 release API 键,在 debug 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
}
}
...
}
...
}
xml 文件包含:
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
MY_DEBUG_API_KEY
</string>
我知道问题出在字符串资源的保留标志上,但如果删除它,可能会搞砸并丢失该字符串资源。 有没有一种方法可以替换实际字符串资源的值,而不是仅仅在构建 gradle 文件中创建一个新字符串?
我只是想一个解决方案也可以是在我使用 Jenkins 环境中的值时排除该文件,但我不知道 android gradle 是否可行系统。有谁知道这是否可行并且更重要,怎么做?
LE:
看来我必须将 res 文件从 main 文件夹移动到 release 文件夹中。因此我现在有以下结构:
- debug
- res
- value
- google_maps_api.xml
- release
- res
- value
- google_maps_api.xml
目前,它似乎是这样工作的。
LLE: 上面的方法行不通,我很快就得出了结论。 xml 文件中的值似乎仍在使用,即使我在 gradle 脚本中声明相同(至少作为名称)也是如此。
作为解决此问题的方法,我实现了以下逻辑:
- 我从 release 文件夹中删除了
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 }
我在local.properties文件
中添加了以下属性google.map.apiKey=MY_API_KEY
我在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) } ... } ... }
我选择了这个解决方案,原因如下:
- 每个用户都可以设置自己的 API KEY 用于调试(local.properties 文件不会影响其他开发人员,因为它永远不会进入存储库)
- Jenkins 可以随时更改它的密钥,而不会影响项目或任何开发人员
- 不需要改变项目的结构或乱用它的资源
- 任何人都可以安全地使用该方法,如果有人没有正确设置 属性,它会抛出一个很好的错误
我希望这能帮助其他有类似问题的人: