Product flavors in android not working - android

I have been stuck on this for a day now. I created 2 flavors for my project and added them under the buildtype in android in build.gradle. I then created a res folder for both and changed the icons for each. When I run the project for any of the variants, it is showing the icon from the project.
My project structure in as follows
[project]
[app]
src
main
res
mipmap
flavor1
flavor2
res
mipmap
and my build.gradle is
productFlavors {
flavor1 {
applicationId "abc"
}
flavor2 {
applicationId "abc"
}
}
sourceSets {
flavo1 {
res.srcDirs = ['src/flavor1/res']
}
flavor2 {
res.srcDirs = ['src/flavor2/res']
}
}
PS: nvm the naming

You should remove the icon from main and leave it only in flavor1 and flavor2 directories.
Also check the names of the flavors in the build.gradle, I think it should be flavor1 instead of flavo1 and flavor2 instead of staging.
Another note, sourceSets definition is not required, standard res directories inside flavors' directories will be used automatically.

Related

Flutter flavor sourceSet resource not refer flavor folder

In my Flutter mobile app have two flavors with separate res folders for each. I have added sourceSet in build.gradle file, but at runtime the running flavor does not show the relavant resource from flavor folder, instead the main folder resources.
Folder structure as below.
src
|
flavor1
------res(with sub folders)
|
flavor2
------res(with sub folders)
|
main
------res(with sub folders)
build.gradle file changes.
android {
sourceSets {
main {
java.srcDirs += 'src/main/kotlin'
res.srcDirs = ['src/main/res']
manifest.srcFile 'src/main/AndroidManifest.xml'
}
flavor1 {
res.srcDirs = [
'src/flavor1/res/drawable-hdpi',
'src/flavor1/res/drawable-ldpi',
'src/flavor1/res/drawable-mdpi',
'src/flavor1/res/drawable-v21',
'src/flavor1/res/drawable-xhdpi',
'src/flavor1/res/drawable-xxhdpi',
'src/flavor1/res/drawable-xxxhdpi',
'src/flavor1/res/drawable',
'src/flavor1/res/mipmap-hdpi',
'src/flavor1/res/mipmap-mdpi',
'src/flavor1/res/mipmap-xhdpi',
'src/flavor1/res/mipmap-xxhdpi',
'src/flavor1/res/mipmap-xxxhdpi',
'src/flavor1/res/raw',
'src/flavor1/res/values',
'src/flavor1/res'
]
manifest.srcFile 'src/flavor1/AndroidManifest.xml'
}
flavor2 {
res.srcDirs = [
'src/flavor2/res/drawable-hdpi',
'src/flavor2/res/drawable-ldpi',
'src/flavor2/res/drawable-mdpi',
'src/flavor2/res/drawable-v21',
'src/flavor2/res/drawable-xhdpi',
'src/flavor2/res/drawable-xxhdpi',
'src/flavor2/res/drawable-xxxhdpi',
'src/flavor2/res/drawable',
'src/flavor2/res/mipmap-hdpi',
'src/flavor2/res/mipmap-mdpi',
'src/flavor2/res/mipmap-xhdpi',
'src/flavor2/res/mipmap-xxhdpi',
'src/flavor2/res/mipmap-xxxhdpi',
'src/flavor2/res/raw',
'src/flavor2/res/values',
'src/flavor2/res'
]
manifest.srcFile 'src/flavor2/AndroidManifest.xml'
}
}
// Because of flavors and multiple res folders.
afterEvaluate {
android.applicationVariants.all { variant ->
tasks.named("generate${variant.name.capitalize()}ResValues")
.configure { task ->
task.outputs.upToDateWhen {false}
}
}
}
flavorDimensions "app"
productFlavors {
flavor1 {
dimension "app"
applicationIdSuffix ""
}
flavor2 {
dimension "app"
applicationIdSuffix ".flavor2"
}
}
}
Running the flavor2 app still refers to main resources is the issue. I want the respective flavor to refer only the given flavor specific resource folder in runtime.
sourceSet in not necessary, just add product flavors within app/build.gradle, folders structure is ok, at compilation time all resources are merged and main folder resources are overridden with flavor resources
just run next command
flutter run --flavor flavor2
more info here: https://medium.com/#salvatoregiordanoo/flavoring-flutter-392aaa875f36

Android: Are there any methods to share a resource betwwen different falvors and sourceset?

I have an application with below source sets and flavors:
flavorDimensions "brand"
productFlavors {
flavor1 {
dimension "brand"
sourceSets {
main {
manifest.srcFile "src/main/flavor1/AndroidManifest.xml"
resources.srcDirs = ['src/flavor1/']
}
}
}
flavor2 {
dimension "brand"
sourceSets {
main {
manifest.srcFile "src/main/flavor2/AndroidManifest.xml"
resources.srcDirs = ['src/flavor2/']
}
}
}
flavor3 {
dimension "brand"
sourceSets {
main {
manifest.srcFile "src/main/flavor3/AndroidManifest.xml"
resources.srcDirs = ['src/flavor3/']
}
}
}
My application is such that 99% of layouts and classes are the same. E.g. only layout file main_activity.xml is different among flavors but the other 20~30 layout files are completely the same. I don't want to copy these 20~30 in three different flavor source set. Are there any ways to share them among three flavors and if a file was present in source set, it overrides the share files? (Such as want android does for drawable and drawble-hdpi , ...)?
So I don't want to have
Unless I have misunderstood the question, you could solve the issue by changing build.gradle like this:
productFlavors {
flavor1 {
dimension "brand"
}
flavor2 {
dimension "brand"
}
//...
}
and structuring your app module like this:
/src
/main
/flavor1
/flavor2
...
and placing all common files(source, resources) in main and the custom/specific files in the flavorX folders which will cause gradle to replace the identically named files in main when each flavor is built.

Product flavors in Android Studio [duplicate]

This question already has answers here:
Reference different assets based on build flavor
(2 answers)
Closed 3 years ago.
I can not get product flavours working. I have this gradle
apply plugin: 'com.android.application'
android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 24
compileSdkVersion 27
}
signingConfigs {
release {
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
signingConfig signingConfigs.release
}
}
repositories {
maven { url "https://jitpack.io" }
}
flavorDimensions "dim1", "dim2", "dim3"
productFlavors {
flavor1 {
dimension "dim1"
applicationId "com.example.dim1.app"
}
flavor3 {
dimension "dim2"
applicationId "com.example.dim2.app"
}
flavor3 {
dimension "dim3"
applicationId "com.example.dim3.app"
}
}
sourceSets {
flavor1 {
java.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/java/"]
manifest.srcFile "W:/android-studio-projects/sharedid/app/src/example1/AndroidManifest.xml"
assets.srcDirs = ["W:/android-studio-projects/sharedid/app/src/example1/assets/"]
resources.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/res/", "W:/android-studio-projects/sharedid/app/src/example1/res/"]
}
flavor2 {
java.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/java/"]
manifest.srcFile "W:/android-studio-projects/sharedid/app/src/example2/AndroidManifest.xml"
assets.srcDirs = ["W:/android-studio-projects/sharedid/app/src/example2/assets/"]
resources.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/res/", "W:/android-studio-projects/sharedid/app/src/example2/res/"]
}
flavor3 {
java.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/java/"]
manifest.srcFile "W:/android-studio-projects/sharedid/app/src/example3/AndroidManifest.xml"
assets.srcDirs = ["W:/android-studio-projects/sharedid/app/src/example3/assets/"]
resources.srcDirs = ["W:/android-studio-projects/sharedid/app/src/main/res/", "W:/android-studio-projects/sharedid/app/src/example3/res/"]
}
}
}
dependencies {
api 'com.google.android.gms:play-services-maps:15.0.0'
api 'com.google.android.gms:play-services-location:15.0.0'
api 'com.android.support:appcompat-v7:27.1.1'
api 'com.github.PhilJay:MPAndroidChart:v2.0.8'
}
...
When I got to "Build | Select variant" I can only select
Module:app
Build Variant:flavor1Flavor2Flavor3Debug,flavor1Flavor2Flavor3Release
I would have liked to get
the following build variants: flavor1Debug,flavor2Debug,flavor3Debug,flavor1Release,flavor2Release,flavor3Release
I have tried "File | Sync project with gradle file"
...
I get this error
Caused by: java.lang.RuntimeException: Cannot read packageName from
W:\android-studio-projects\sharedid\app\src\main\AndroidManifest.xml
I have tried to both
have no such file (hoping it would take the product flavor one?)
have the "main" manifest only define shared stuff between all product flavors
Just try like below,
flavorDimensions "dim1"
productFlavors {
flavor1 {
dimension "dim1"
applicationId "com.example.dim1.app"
}
flavor3 {
dimension "dim1"
applicationId "com.example.dim2.app"
}
flavor3 {
dimension "dim1"
applicationId "com.example.dim3.app"
}
}
For more details about build variant see this link
I think there are two unrelated problems :
Currently you have 2 build types (the automatically created debug and release) and 3 dimensions (dim1, dim2 and dim3), each one having 1 variant (flavor1 for dim1, flavor2 for dim2, ...)
this gives at most :
2 * 1 * 1 * 1 = 2 combinations
You should switch to 2 build types and 1 dimension (say dim1) having 3 variants (flavor1, flaver2 and flavor3) to have :
2 * 3 = 6 apks
You should have a main manifest. Unlike other resources the manifest is not simply overriden but merged from multiple sources (see Merge Multiple Manifest Files for more details).
It should at least contains a package name (possibly different from the final applicationId(s)) as explained by this note from Configure Product Flavors :
Note : You still need to specify a package name using the package attribute
in the main/ manifest file. You must also use that package name in
your source code to refer to the R class, or resolve any relative
activity or service registration. This allows you to use applicationId
to give each product flavor a unique ID for packaging and
distribution, without having to change your source code.
I would have liked to get
the following build variants:
flavor1Debug,flavor2Debug,flavor3Debug,flavor1Release,flavor2Release,flavor3Release
For this, you need to define the same dimension for all flavors.
I get this error
Caused by: java.lang.RuntimeException: Cannot read packageName from
W:\android-studio-projects\sharedid\app\src\main\AndroidManifest.xml
You get this error because the path is not reachable.
Just think, how can app find W: when it is running?
So, you need to use a relative path here.
Also from official documentation (https://developer.android.com/studio/build/build-variants#configure-sourcesets):
If you have sources that are not organized into the default source set
file structure that Gradle expects, as described above in the section
about creating source sets, you can use the sourceSets block to change
where Gradle looks to gather files for each component of a source set.
You don't need to relocate the files; you only need to provide Gradle
with the path(s), relative to the module-level build.gradle file,
where Gradle should expect to find files for each source set component

Android Gradle identify current falvor at compile time

How is it possible to identify the current flavor being compiled. I'm trying to add a file to compile only if I'm compiling a certain product flavor.
buildTypes {
android.applicationVariants.all { variant ->
variant.productFlavors.each() { flavor ->
if (flavor.name.equals(currentFlavorName)) {
The problem is that I can't seem to find where the currentFlavourName of the flavor which I am currently building is located.
just put the strings you want for flavor1 into:
src/flavor1/res/values/strings.xml
and the strings for flavor2 into:
src/flavor2/res/values/strings.xml
no need to put logic into your gradle file
Android uses a unique build process regarding your resources for different flavors and it is very easy to control.
if you set up your main source:
project-name
------------/app
---------------/src
-------------------/main
------------------------/res
----------------------------/values
------------------------/java
-------------------/development
-------------------------------/res
-----------------------------------/values
-------------------------------/java
-------------------/production
------------------------------/res
----------------------------------/values
------------------------------/java
This would be a bottom up approach from product flavor into main. Meaning if you have a strings.xml with items having the same name existing in development/res/values and have values that also exist in main/res/values/strings.xml these will be over written (and same would go for the production flavor) based on the build variant defined in your gradle file.
android {
productFlavors {
production {
applicationId "com.test.prod"
versionName "1.0.0"
}
development {
applicationId "com.test.dev"
versionName "1.0.0"
}
}
I don't know if exits a method to get the currentFlavor. I haven't found it yet.
A ugly solution can be
variant.productFlavors.each() { flavor ->
if (flavor.name.equals("flavor1")) {
//..........
}
}
However, if you want to be able to control which strings.xml you are using, you can achieve it in different ways.
First of all you can just define a xml file in your flavor folder.
app/src/main/res/values/ -> for common resources
app/src/flavor1/res/values -> resources for flavor1
app/src/flavor2/res/values -> resources for flavor2
This doesn't require any config in your build.gradle script.
A second option is to define a resource value using build.gradle.
Something like:
productFlavors {
flavor1 {
resValue "string", "app_name", "IRCEnterprise"
}
//....
}
Another option is to create some field in your BuildConfig class using this kind of script.
productFlavors {
flavor1 {
buildConfigField "String", "name", "\"MY FLAVOR NAME\""
}
}

Combine BuildType and Flavor resources

I have 2 versions of app: paid-app and free-app. I use gradle and Android Studio.
I have next folder structure:
src folder, and inside it 3 folders: main, paidapp, freeapp - where paidapp and freeapp are flavors.
My configs:
defaultConfig {
applicationId "com.company"
}
buildTypes {
debug {
applicationIdSuffix '.dev'
}
}
productFlavors {
freeapp {
}
paidapp {
applicationId 'com.company.paidapp'
}
}
What I want: have on my phone 4 apps:
package com.company.dev, name "dev freeapp"
package com.company.paidapp.dev, name "dev paidapp"
package com.company, name "freeapp"
package com.company.paidapp, name "paidapp"
package is ok, gradle manage it automatically, but how to create different names for app?
App name located in strings.xml
in src/paidapp/res/values/strings.xml:
<string name="appName">dev paidapp</string>
in src/freeapp/res/values/strings.xml:
<string name="appName">dev freeapp</string>
I looked there - http://tools.android.com/tech-docs/new-build-system/resource-merging
The priority order is the following:
BuildType -> Flavor -> main -> Dependencies.
So I can chose or string from BuildType or from Flavor, but how to combine BuildType and Flavor?
Just create a folder src/freeappRelease/res/values/ and add your very specific strings in this folder.

Categories

Resources