10

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?

Abhinav singh
  • 1,448
  • 1
  • 14
  • 31
Nunes D.
  • 213
  • 1
  • 3
  • 11
  • See http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename for more details on this. – and_dev Nov 25 '15 at 14:15
  • 1
    The documentation doesn't say anything about setting the applicationId for flavorDimensions. – Nunes D. Nov 26 '15 at 08:59
  • So http://stackoverflow.com/a/26585241/4310905 is nearly the same so your code looks OK. – and_dev Nov 26 '15 at 09:30
  • 1
    The solution proposed by @fredrik stopped working after gradle plugin 1.0.0. My code it's ok, except the fact that for google-services.json processYYYXXXDebugGoogleServices is not getting the applicationId. – Nunes D. Nov 26 '15 at 17:12

2 Answers2

7

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
}
laomo
  • 436
  • 4
  • 12
1

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.

Elyes Mansour
  • 126
  • 1
  • 6