Reputation: 6314
I have an special case where I need to override google map key string variable when building with Jenkins. I have setup an special structure like this:
- debug
- res
- value
- google_maps_api.xml
- main
- res
- value
- google_maps_api.xml
Thus, in the main res file I put the release API key and in the debug res file I put the debug API key (for the machine I'm working on - generated for the debug.keystore of Android).
In the build gradle file I have this basic logic for creating an string resource based on what was setup on Jenkins environment:
String googleMapApiKey = System.env.MAP_API_KEY;
...
android {
...
buildTypes {
...
debug {
if (null != googleMapApiKey && !googleMapApiKey.equals("null")) {
resValue "string", "google_maps_key", googleMapApiKey
}
}
...
}
...
}
the xml file contains this:
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
MY_DEBUG_API_KEY
</string>
I know the issue is because of the preserve flag of the string resource, but if remove that there are chances things get messed up and to loose that string resource. Is there an way I can replace the value of the actual string resource instead of just creating a new one in the build gradle file?
I was just thinking that an solution can also be to exclude that file when I'm using the value from Jenkins environment, but I do not know if it is doable with android gradle system. Does anyone know if this is doable and more important, how?
LE:
It seemed I had to move the res file from the main folder into the release one. Thus I have the following structure now:
- debug
- res
- value
- google_maps_api.xml
- release
- res
- value
- google_maps_api.xml
For now, it seems to be working like this.
LLE: The method from above doesn't work, I was fast on the conclusions. It seems the value from the xml file is still used, even if I declared the same(at least as name) in gradle script.
Upvotes: 2
Views: 3252
Reputation: 6314
As an workaround for this I have implemented the following logic:
google_maps_api.xml
from release folderI have created an custom method which loads an property from 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
}
I have added the following property in local.properties file
google.map.apiKey=MY_API_KEY
I have added the following logic in the 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)
}
...
}
...
}
I've chosen this solution, because of the following reasons:
I hope this helps others that have an similar issue:
Upvotes: 6