Android Studio - Gradle: How to replace variables in a file - android

Im fairly new to Gradle and have been using Eclipse and Ant to do all the builds. Within our app we have a config.properties file located in the assets folder at the same level as src and res etc. In this file we have the following:
developmentsettings=true
defaultLogLevel=4
prodEnvironment=false
How can I replace the values of these 3 variables in the build.gradle file? Do I create a new task for this, and if so, is this within the android tag or not?
Any and all help would be must appreciated

I'm not sure if you specifically need these in a separate file... but if not, BuildConfig seems like the way to go. You do something like this in your gradle file:
buildTypes {
debug {
buildConfigField "boolean" "DEVELOPMENT_SETTINGS" "true"
buildConfigField "int" "DEFAULT_LOG_LEVEL" "4"
buildConfigField "boolean" "PROD_ENVIRONMENT" "false"
}
release {
buildConfigField "boolean" "DEVELOPMENT_SETTINGS" "false"
buildConfigField "int" "DEFAULT_LOG_LEVEL" "4"
buildConfigField "boolean" "PROD_ENVIRONMENT" "true"
}
}
And then from your source android code, you reference these fields like so:
BuildConfig.DEVELOPMENT_SETTINGS
BuildConfig.DEFAULT_LOG_LEVEL
BuildConfig.PROD_ENVIRONMENT
You're essentially declaring constants, from gradle, that can be used in your java code.

At build.gradle set the following
android {
buildTypes {
debug{
resValue "string", "app_name", "My App Name Debug"
}
release {
resValue "string", "app_name", "My App Name"
}
}
}
You can access them in the usual way with #string/app_name or R.string.app_name

You can let the build system include different versions of the assets/config.properties file depending on whether you're doing a debug or release build. To do this, don't put the file in src/main/res/assets/config.properties; instead, put the debug version in src/debug/res/assets/config.properties and the release version in src/release/res/assets/config.properties. The build system will pick the right version when it does the corresponding build.

Related

Overwrite specific class only in one buildType

In my app I have 3 BuildTypes: Debug, Release and Internal. I have one class Networking, this class is the same in Debug and Release but different in Internal. Can I create a project structure so that I do not have to duplicate the class in Debug and Release but only maintain two version: One Debug/Release and one that will overwrite this one when I build the Internal type?
Sadly other project structure does not allow me to use productFlavors for this, so I have to use the buildTypes.
TL;DR Is there a way to set a default Class for any build type and overwrite it in only one specific build type without having to copy the class in each build-type folder?
You can use the buildConfigField variable in your build.gradle, and set it to different values in each buildType. Something like:
buildTypes {
debug {
buildConfigField "boolean", "USE_INTERNAL_CLASS", "false"
}
release {
buildConfigField "boolean", "USE_INTERNAL_CLASS", "false"
}
internal {
buildConfigField "boolean", "USE_INTERNAL_CLASS", "true"
}
}
You can then access that variable at runtime using BuildConfig.USE_INTERNAL_CLASS, and then do whatever you want, depending on whether it's true or false

How to create a file and set in environment variable and get the data inside the file in build.gradle?

I have some secret keys which I want to store in a File, define the path in the environment variable and then get the values inside it in build.gradle.
I have a file - somekeys and there are 2 3 key-value pair -
(Key1 - value 1)
(Key2 - value 2)
(key3 - value 3)
I will define the path of the file in the system variable. SOME_KEY and its path.
I get the file inside the gradle using - System.getenv("SOME_KEY")
Now that I have the file How to extract the value from the keys inside the file.
And then pass it to the build(release and debug) type keys like this -
resValue "string", "fc_app_id", "getting the key from the file in environment variable".
This can be done by adding your key to the gradle.properties file.
This file can be found in .gradle directory in your home directory. You might have to create the file if it's not there already.
Just add the key as key-value pair in gradle.properties file as shown
below.
SECRET_KEY="my-super-secret-key123"
In your module level build.gradle file add the key as a buildConfigField and if you want to use the key in xml or app code add the key as a resValue.
buildTypes {
debug {
buildConfigField 'String', "SecretKey", SECRET_KEY
resValue 'string', "secret_key", SECRET_KEY
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField 'String', "SecretKey", SECRET_KEY
resValue 'string', "secret_key", SECRET_KEY
}
}
This code can be accessed as shown below:
String apiKey = BuildConfig.ApiKey;
I recommend the documentation around properties and this other question if you really want to load your own file.

Android : resValue variables could not be resolved in Gradle

I am following an android example from vogella.com about Retrofit.
http://www.vogella.com/tutorials/Retrofit/article.html
I get stuck where one is supposed to do the following:
add the stackapp id and key
According to Vogella
After you registered your application, you get a Client Id and a Key . As we want to keep them out of a possible version control system, we import them into our project using gradle. To do so, go to your gradle home directory (.gradle/ in your users home directory) and paste the following lines into your gradle.properties file (create one, if you can’t find it). Of course, replace yourKey and yourClientId with your corresponding values from Stackapps.
I went to this directory and created a new file
gradle.properties
and in that file I added the keys
key=xxxxxxxx
client_id=xxxx
and then in the gradle.properties i added the following in deafultconfig {
resValue("string", "key", project.key)
resValue("string", "client_id", project.client_id)
But both the key and the client_id's could not be resolved.
What could the solution be to this?
Try to change the sintax :
resValue "string", "key", project.key
resValue "string", "client_id", project.client_id
And dont forget to add the variables inside your gradle file:
ext.key = "your_key"
ext.client_id = 0
The third parameter should be a String, and you may should define the key and cliend_id in local.properties and use code below:
Properties lp = new Properties()
lp.load(newInputStreamReader(project.rootProject.file('local.properties').newInputStream(), StandardCharsets.UTF_8))
resValue "string", "key", p.getProperty('key', '0')//default "0"
resValue "string", "client_id", p.getProperty('client_id', '0')

Change string resource by flavor / debug-build

Let's say we have strings_test.xml, which stores string values for testing and should be shown in a debug-release. When the apk gets build as a release version all values should be change to an empty string e.g. <string name="test_some_card_text">#string/empty</string>.
Is there a possibility to achieve this?
As always, thanks in advance.
Yes you can do that inside your app gradle under buildTypes..
buildTypes {
mybuild {
resValue "string", "test_some_card_text", '"test"'
resValue "string", "other_text", '"other"'
}
debug {
resValue "string", "test_some_card_text", '"test"'
resValue "string", "other_text", '"other"'
}
}
Then access it like this.
getApplicationContext().getResources().getString(R.string.test_some_card_text);
getApplicationContext().getResources().getString(R.string.other_text);
For build you need to select that build variants and have to build it.
Yes, Gradle lets you override strings.
Add this inside buildTypes{} in your app/build.gradle
debug {
applicationIdSuffix "debug"
}
That should create a directory titled debug next to main. If not then manually create one. (Seriously, I haven't tried this, but I know this is possible.)
Then if your strings_test.xml is under res/values, create similar directory structure under debug/ and put your strings_text.xml with debug specific strings there. This will show up in your debug build. The ones under release/main/res/values will show up in your release build.
PS: You can override all res and asset data like this according to buildTypes and flavor. You can't override Java files though, you could however add them.
As #Aditya Naik said it is possible using Flavors.
Official doc says
BuildType -> Flavor -> main -> Dependencies.
This means that if a resource is declared in both the Build Type and in main, the one from Build Type will be selected.
Note that for the scope of the merging, resources of the same (type, name) but different qualifiers are handled separately.
This means that if src/main/res has
res/layout/foo.xml
res/layout-land/foo.xml
and src/debug/res has
res/layout/foo.xml
Then the merged resource folder will contain the default foo.xml from src/debug/res but the landscape version from src/main/res
for more info visit Official doc - Resource Merging
It is not possible to change the string value after creation of the apk.
But you can assing the value to text or edittext ... etx dynamically after creation of the apk.
For those who come here looking for some way to apply a similar method to raw resources, I dealt with it using buildConfigField.
gradle
...
buildTypes {
debug {
...
buildConfigField "int", "shared_resource_name", 'R.raw.debug_resource_name'
...
}
prod {
...
buildConfigField "int", "shared_resource_name", 'R.raw.prod_resource_name'
...
}
}
Pay attention to the quotes. After that, place BuildConfig.shared_resource_name in the files wherever R.raw.resource_value used to be accessed directly.
This can be used to other resources I think.

Declare variables in gradle to use in Android project

I am reading config fields from an environment.properties file that I would like to reuse in my Android application. I have tried various ways to get values from gradle's build without success (Gradle 2.7):
buildTypes {
debug {
buildConfigField "String", "SERVER_SCHEME", getBuildConfigField('SERVER_SCHEME')
buildConfigField "String", "SERVER_BASE_URL", getBuildConfigField('SERVER_BASE_URL')
buildConfigField "int", "SERVER_PORT", getBuildConfigField('SERVER_PORT')
buildConfigField "String", "SERVER_CONTEXT", getBuildConfigField('SERVER_CONTEXT')
}
}
where getBuildConfigFields(key) is a function defined in my config.gradlereading a file and returning the value corresponding to the specified key.
I have tried :
buildConfigField "TYPE" "KEY" "VALUE",
buildConfigField("TYPE" "KEY" "VALUE")
resValue "TYPE" "KEY" "VALUE"
But none of the are working with gradle errors like :
Error:(71, 0) Gradle DSL method not found: 'buildConfigField()' Possible causes:
The project 'app' may be using a version of Gradle that does not contain the method. Gradle settings
The build file may be missing a Gradle plugin. Apply Gradle plugin
I am using gradle 2.7 to build my android app and found these ways to set BuildConfigFields in different answers like this one but they seem to be outdated for newer versions. What functions can I use to get values from gradle in my application ?
Thank you !

Categories

Resources