Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to set Android applicationId when using flavor dimensions?

I'm using flavor dimensions in my project, and I have been using a for loop to set the applicationId to my generated flavors:

flavorDimensions "appname", "brand"

productFlavors {

   user {
        dimension "appname"
   }

   installer {
        dimension "appname"
   }

   branda {
        dimension "brand"
   }

   brandb {
        dimension "brand"
   }

   brandc {
        dimension "brand"
   }

   brandd {
        dimension "brand"
   }

}

An I filter those that I do not support right now:

variantFilter { variant ->
  def names = variant.flavors*.name

  if (names.contains("installer") && (names.contains("brandc") || names.contains("brancd")) ) {
      variant.ignore = true
  }
}

Then I update the applicationId according the flavor name:

applicationVariants.all { variant ->
def flavorString = variant.getVariantData().getVariantConfiguration().getFlavorName()
def mergedFlavour = variant.getVariantData().getVariantConfiguration().getMergedFlavor();

switch (flavorString) {
/**
 * user
 */
case "userBranda":
  mergedFlavour.setApplicationId("com.mycompany.product.user.someName")
  mergedFlavour.setVersionName("1.0.0")
  break
case "userBrandb":
  mergedFlavour.setApplicationId("com.mycompany.product.user.b")
  mergedFlavour.setVersionName("2.0.0")
break
case "userBrandc":
  mergedFlavour.setApplicationId("com.mycompany.product.user.otherName")
  mergedFlavour.setVersionName("1.5.0")
  break
case "userBrandd":
  mergedFlavour.setApplicationId("com.mycompany.product.user.d")
  mergedFlavour.setVersionName("1.0.1")
  break
/**
 * installer
 */
case "installerBranda":
  mergedFlavour.setApplicationId("com.mycompany.product.installer.marketingName")
  mergedFlavour.setVersionName("1.0.0")
  break
case "installerBrandb":
  mergedFlavour.setApplicationId("com.mycompany.product.installer.b")
  mergedFlavour.setVersionName("1.0.0")
  break
default:
  throw new GradleException("flavor ${flavorString} is not supported, please configure it first...")
  break
}

I have two questions:

1 - Is this the right way to do it? The android plugin does not support a way to configure the applicationId using flavorDimensions?

2 - The configuration I mention here works in most of the cases, except for example if you're using a google-services.json that has the application package already defined inside. For simple productFlavor usage, the configuration works normally, but if I use flavor dimensions, gradle is always complaining:

:app:processUserBrandaDebugGoogleServices
No matching client found for package name 'com.mycompany.product'

Basically the 'com.mycompany.product' is the package that is defined by default in the AndroidManifest.xml. If I look in the

app/build/intermediates/manifests/full/userBranda/debug/AndroidManifest.xml

I can see that the package was replaced with success.

What I can conclude about it is that, only for flavor dimensions, somehow gradle merges the manifests only after the processUserBrandaDebugGoogleServices, which means that at this point, the package defined in the manifest still is the default one.

Anyone with the same problem here? How to workaround this issue? Is this an android gradle plugin bug?

like image 862
Nunes D. Avatar asked Nov 24 '15 12:11

Nunes D.


People also ask

What is Flavour dimension android?

Flavor Dimensions is a way to group flavors by a name. For now, we're using just a single group. Add the following line in your defaultConfig block: flavorDimensions "default" Now syncing the gradle would give you the following product flavors: Android Build Variants combine build types and product flavors.

When would you use product flavor in your build setup?

When to use Product Flavors. When we want to address the issue of having separate project code for each version of the app while still having one project code. Given a scenario where you have a free and a paid app you can limit features in the free and expose all the other features in the paid version of the app.

What is build flavor in android?

Android Product Flavors are also known as Android build types or Android build variants are the native Android app development way to implement different versions of the same application with minor changes.


Video Answer


2 Answers

In short, the keyword is applicationIdSuffix,like this:

productFlavors {
    pro {
        applicationIdSuffix = ".pro"
    }
    free {
        applicationIdSuffix = ".free"
    }
}

buildTypes {
    debug {
        applicationIdSuffix ".debug"
    }
}

More powerful, you can do like this:

applicationVariants.all { variant ->
    def flavorData = rootProject.ext[variant.buildType.name]

    variant.mergedFlavor.setApplicationId(flavorData.applicationId)
    //do other things
}
like image 161
laomo Avatar answered Sep 18 '22 14:09

laomo


I struggled with this problem as well. The solution that worked for was to write apply plugin: 'com.google.gms.google-services' after the android{} groovy code block to ensure that when the plugin code is executed, the correct applicationId would have already been setup.

like image 37
Elyes Mansour Avatar answered Sep 21 '22 14:09

Elyes Mansour