Android override file for flavour - android

In my android app I have a file that I want to override for a specific flavor.
My structure:
However when I build the funki flavour I still see that the Computer class from main is used.
In my build.gradle I have:
productFlavors {
somename{
resValue "string", "app_name", "some name"
}
funki {
resValue "string", "app_name", "Funki App"
applicationIdSuffix ".funki"
}
}
Every build I see that the Computer file from main is used.
All the other overrides e,g, res files are overriden based on the flavor i build.
How can I override a class for a specific flavor?

You should be getting a "duplicate class" build error — at least, that used to be the behavior. You cannot override a Java/Kotlin class in a flavor.
What you can do is remove the Java/Kotlin class from the main source set and have it in all of your flavors. So, move Computer.java from main to somename, and keep your other Computer.java in funki.

I ended up checking the productflavor inside the code like:
if(BuildConfig.FLAVOR.equals("funki")){
Based on the if/else I execute my desired code.

Related

How can I display the build time in my Android application?

When I develop my application and correct it once and again, I would like to see if the one running now is the last I built. Hence, I would like to add a field, say a TextView, that will display the build time-of-day (e.g., 19:26).
How can I take the build time and embed it in activity_main.xml?
BTW - build version, a counter that progresses with every build, is also good. Anything that will indicate the last build.
Assuming that you're building with Gradle, you can add a BuildConfig field with the desired information in your app/build.gradle:
android {
defaultConfig {
def buildTime = new Date()
buildConfigField "String", "BUILD_TIME", "\"${buildTime.format('yyyy-MM-dd HH:mm:ss')}\""
... other stuff ...
}
...other stuff ...
}
And then in your Kotlin/Java code:
myTextView.text = BuildConfig.BUILD_TIME
Another alternative is to replace the buildConfigField line in the above example with:
resValue "string", "build_time", "${buildTime.format('yyyy-MM-dd HH:mm:ss')}"
Which creates a string resource that you can use in your layout XML file, e.g.:
android:text="#string/build_time"

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.

How to create different build variants pointing to different Servers?

I am using gradle.build for auto building my app. I want to generate three different APK's each pointing to different Service URL's.
How can I make use of buildVariants (productFlavors in gradle). But I'm not able to figure out where to set the three URL's in the Gradle.
How can I do this?
It is really easy to do with gradle.
productFlavors {
first_server {
buildConfigField "String", "SERVER_URL", "\"https://first_server_url/\""
}
second_server {
buildConfigField "String", "SERVER_URL", "\"https://second_server_url/\""
}
}
You may want to find more information here.
So later you can easy access this variable by BuildConfig.SERVER_URL
You can use as like following,
In Gradle:
productFlavors{
serverone {
applicationId "com.example.krishna.mysample.serverone"
version 1.1
}
servertwo {
applicationId "com.example.krishna.mysample.servertwo"
version 1.1
}
serverthree {
applicationId "com.example.krishna.mysample.serverthree"
version 1.1
}
}
In folder structure In App:
src
-->main
-->serverone
-->servertwo
-->serverthree
If MainActivity is required to different logic then, that MainActivity is place in serverone, servertwo and serverthree folder remaining classes are keep in main folder only. And do diffent functionality on that Activities.

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

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.

How to define static String values in Android that change for test configurations with Gradle?

Hey I am trying to statically define String values that change according to the configuration I am running. So if I run a test configuration, it uses the test API url, but if I run a regular build, it statically sets the real API URL.
I am using two strings files right now, one in the main folder and one in the androidTest folder in Android Studio. This works well for getting different Strings per configuration, but I'de like to do it statically rather than dealing with Resource fetches.
Is this possible?
I have seen this answer for ANT, but I am not sure how to do it with Gradle.
You can generate gradle constants like this:
build.gradle
android {
buildTypes {
debug {
buildConfigField "String", "FOO", "\"foo\""
}
release {
buildConfigField "String", "FOO", "\"bar\""
}
}
}
And access them in your code through BuildConfig.FOO
Note you may need to clean and/or restart your IDE for the to come in to effect.

Categories

Resources