Here is a problem, for example, I need the next three dimensions for my app: "brand", "environment", "market". The configuration will look like this:
flavorDimensions "brand", "environment", "market"
productFlavors {
// brand
nike{
dimension "brand"
applicationId "com.android.nike"
}
adidas{
dimension "brand"
applicationId "com.android.adidas"
}
// environment
test{
dimension "environment"
applicationIdSuffix ".test"
}
prod {
dimension "environment"
}
// market
google {
dimension "market"
}
amazon {
dimension "market"
}
}
As a result, I can build the next 8 applications (I ignoring build types in this example):
nikeTestGoogle
nikeTestAmazon
nikeProdGoogle
nikeProdAmazon
adidasTestGoogle
adidasTestAmazon
adidasProdGoogle
adidasProdAmazon
As I understand documentation about flavor dimensions (https://developer.android.com/studio/build/build-variants#flavor-dimensions), application nikeTestGoogle use files from the next folders: main, nike, test, google, nikeTest, nikeTestGoogle. But it doesn't work, Android studio sees only files in main, nike, test, google, and nikeTestGoogle. Files in nikeTest ignored and even doesn't mark as currently active.
Does anyone know why it happened?
I have an Android project with 5 flavors and 2 flavorDimensions.
See Below:
flavorDimensions "env", "device"
productFlavors {
dev {
applicationIdSuffix ".dev"
dimension "env"
}
staging {
applicationIdSuffix ".staging"
dimension "env"
}
prod {
applicationIdSuffix ""
dimension "env"
}
amazon {
dimension "device"
}
google {
dimension "device"
}
}
Is there a way to only include a dependency to one flavorDimension instead of just one flavor? Basically I have a dependency I only want included in googleDev, googleStaging, and googleProd (but not the amazon dimension)
Is there an easy way to do this without repeating each dependency 3 times?
I have android application with different builds:
com.my.application.dev
com.my.application.test
com.my.application.release
but they are signed with same signature.
When i try to install on device few builds simultaneously, i get error
"package with this name already exist".
Is it ok?
Is this correct behavior?
You could use applicationIdSuffix which is:
Application id suffix. It is appended to the "base" application id
when calculating the final application id for a variant.
For example:
android {
...
defaultConfig {...}
buildTypes {
debug{...}
release{...}
}
flavorDimensions "version"
productFlavors {
demo {
dimension "version"
applicationIdSuffix ".demo"
}
full {
dimension "version"
applicationIdSuffix ".full"
}
}
}
I found the cause of this problem.
There was a problem with the content provider, builds had different packages but tried to add content providers with the same name
I have multi dimensionFlavor as:
flavorDimensions "app", "endpoint"
productFlavors {
ph {
applicationIdSuffix ".app1"
dimension "app"
}
pac {
applicationIdSuffix ".app2"
dimension "app"
}
production {
dimension "endpoint"
// applicationIdSuffix ".production"
}
staging {
dimension "endpoint"
// applicationIdSuffix ".staging"
}
}
But I want the application id to have both the app and env name. like: com.company.application.app1.staging
And then comes the confusion in the directory structure to put the google-services.json separately for each package name.
I've tried like app/src/app1Staging/google-services.json
But it fails in the build.
google-services.json should be put under assets directory and accessed via AssetManager, something like AssetManager assetMgr = activity.getAssets();
And the paths should be organised according to your build flavors, e.g.
app/src/staging/assets/google-services.json
I'm trying to work with build flavors. In my build.gradle I've defined 2 flavors, a normal flavor and an admin flavor.
Basicly, the admin flavor has an extra button on the main activity.
I understand that I can define different packages/classes for different flavors. But is there a way to make a sort of if case to add/remove a piece of code depending on the flavor?
Basicly, I would need two versions of an Activity. But I don't want two entire different versions of the activity and maintain them.
So in my activity I would like to do
=> gradle check if flavor is 'admin'
=> if yes, add this code of the button
Is this possible? Or would you need two different physical activities and thus maintain both of them when you add functionality afterwards.
BuildConfig.FLAVOR gives you combined product flavor.
So if you have only one flavor dimension:
productFlavors {
normal {
}
admin {
}
}
Then you can just check it:
if (BuildConfig.FLAVOR.equals("admin")) {
...
}
But if you have multiple flavor dimensions:
flavorDimensions "access", "color"
productFlavors {
normal {
dimension "access"
}
admin {
dimension "access"
}
red {
dimension "color"
}
blue {
dimension "color"
}
}
there are also BuildConfig.FLAVOR_access and BuildConfig.FLAVOR_color fields so you should check it like this:
if (BuildConfig.FLAVOR_access.equals("admin")) {
...
}
And BuildConfig.FLAVOR contains full flavor name. For example, adminBlue.
To avoid plain string in the condition, you can define a boolean property:
productFlavors {
normal {
flavorDimension "access"
buildConfigField 'boolean', 'IS_ADMIN', 'false'
}
admin {
flavorDimension "access"
buildConfigField 'boolean', 'IS_ADMIN', 'true'
}
}
Then you can use it like this:
if (BuildConfig.IS_ADMIN) {
...
}
You can define either different build configuration fields or different resource values (like string values) per flavor, e.g. (as per Google's gradle tips and recipes), e.g.,
android {
...
buildTypes {
release {
// These values are defined only for the release build, which
// is typically used for full builds and continuous builds.
buildConfigField("String", "BUILD_TIME", "\"${minutesSinceEpoch}\"")
resValue("string", "build_time", "${minutesSinceEpoch}")
...
}
debug {
// Use static values for incremental builds to ensure that
// resource files and BuildConfig aren't rebuilt with each run.
// If they were dynamic, they would prevent certain benefits of
// Instant Run as well as Gradle UP-TO-DATE checks.
buildConfigField("String", "BUILD_TIME", "\"0\"")
resValue("string", "build_time", "0")
}
}
}
So in this case, something like
productFlavors {
normal {
dimension "access"
buildConfigField("boolean", "IS_ADMIN", "false")
}
admin {
dimension "access"
buildConfigField("boolean", "IS_ADMIN", "true")
}
}
and then use it like
if (BuildConfig.IS_ADMIN) {
...
} else {
...
}
or if it is just to have different string values for different flavors, it can be done with different resValues and then you don't even need the if/then
You can try this way
productFlavors {
def app_name = "you app name"
development {
versionCode 1
versionName "1.0.1"
buildConfigField 'String', 'varibalename', ""
}
release {
versionCode 1
versionName "1.0.1"
buildConfigField 'String', 'varibalename', ""
}
}
if(BuildConfig.varibalename){}