Gradle variable from another applicationId flavor - android

I need to build an application created with a flavor and create a dynamic variable who points to an applicationId of another flavor (Because the code of an internal library uses the applicationId of other applications) but I don't know how to do that.
Here is the sample code :
defaultConfig {
applicationId "com.sample.mycompany"
}
buildTypes {
release {
}
qualif {
applicationIdSuffix = ".qual"
}
debug {
applicationIdSuffix = ".dev"
}
}
flavorDimensions "client", "nature"
productFlavors {
ClientA {
dimension "client"
applicationIdSuffix = ".A"
}
ClientB {
dimension "client"
applicationIdSuffix = ".B"
}
NatureX {
dimension "nature"
applicationIdSuffix = ".X"
}
NatureY {
dimension "nature"
applicationIdSuffix = ".Y"
// A buildconfigField variable here to get com.sample.mycompany[client].X[buildTypes]
}
NatureZ {
dimension "nature"
applicationIdSuffix = ".Z"
// A buildConfigField variable here to get com.sample.mycompany[client].X[buildTypes]
}
}
When I compile with the Build Variant : ClientANatureYDebug
, final applicationId is com.sample.mycompany.A.Y.dev
I want a dynamic variable with buildConfigField (or something else to retrieve the new variable in Java) who is com.sample.mycompany.A.X.dev
I think to get the final applicationId and replace the applicationIdSuffix of the current nature compilation dimension by .X and get the result in a new variable but I do not know how. Can you help me ?

Fixed with :
buildConfigField "String", "VAL_SHARE_TO_RECEIVER_APP_ID", "APPLICATION_ID.replace(\".Y\", \".X\")"

Related

How to make BuildConfigField value dynamic in gradle?

I want to make HostName field dynamic. so I can have different HostName for both app1 and app2, for develop and release
**app1 {
dimension "client"
applicationId = "com.app1.random"
}
app2 {
dimension "client"
applicationId = "com.app2.random"
}
develop {
dimension "environment"
buildConfigField "String", "HOSTNAME", "\"https://app1.example.com\""
}
release {
dimension "environment"
buildConfigField "String", "HOSTNAME", "\"https://app1.com\""
}**
Hope this help you
flavorDimensions "default"
productFlavors{
develop {
buildConfigField "String", "HOSTNAME", "\"https://app1.example.com\""
}
release {
buildConfigField "String", "HOSTNAME", "\"https://app1.com\""
}
}

Is there an easy way include common feature settings in gradle

Is there an easy way to include common flavor settings in a flavor when the flavors are split out by build settings?
Take the below example. I'd like to have all the settings in the flavor1 group below included in both the Debug and Release flavors. This is obviously a simplified example, as I have 4 flavors and over 20 settings common between them and I don't wan to duplicate them.
android {
productFlavors {
flavor1Debug {
resValue 'string', 'application_name', 'DebugName'
}
flavor1Release {
resValue 'string', 'application_name', 'RelaseName'
}
//flavor1 {
// buildConfigField 'String', 'DEFAULT_LANGUAGE_CODE', '"en"'
//}
}
}
There is a defaultConfig section, you can provide the base configuration for all flavors in the defaultConfig block, and each flavor can change any of these default values.
for example:
android {
defaultConfig {
manifestPlaceholders = [hostName:"www.example.com"]
...
}
buildTypes {
debug{...}
release{...}
}
flavorDimensions "version"
productFlavors {
demo {
dimension "version"
manifestPlaceholders = [hostName:"www.otherexample.com"]//this flavor change manifestPlaceholders
...
}
full {
dimension "version" //this flavor extends manifestPlaceholders from `defaultConfig`
...
}
}

Declare variable into build.gradle that match the applicationId with flavors suffix

I don't figure out how can I set a resource value (resValue) in my build.gradle, depending on the build variant selection.
Here a bit of explanation.
I'm working with the Skype For Business SDK (hereafter referred to as Sfb) and during is implementation, it ask me to add a resource value named ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE.
So I was looking in their application example (available here) and found that in build.gradle they have added as follow the corresponding value :
android {
...
defaultConfig {
applicationId "com.microsoft.office.sfb.sfbdemo"
...
resValue ("string", "ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE", "${applicationId}"
}
...
}
This value then used in a SfbSDK class, checking if it match the application package name.
And here is my trouble, I work with different flavorDimensions as describe in my build.gradle below.
apply plugin: 'com.android.application'
...
android {
...
defaultConfig {
applicationId "com.tsp.test"
...
resValue ("string", "ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE", "${applicationId}"
}
...
flavorDimensions("customer", "version")
productFlavors {
a {
dimension "customer"
applicationIdSuffix ".a"
}
b {
dimension "customer"
applicationIdSuffix ".b"
}
alpha {
dimension "version"
applicationIdSuffix ".alpha"
}
beta {
dimension "version"
applicationIdSuffix ".beta"
}
release {
dimension "version"
applicationIdSuffix ".release"
}
}
}
...
Depending on my build variant selection, this will generate me 6 different APK :
com.tsp.test.a.alpha ; com.tsp.test.a.beta ; com.tsp.test.a.release
com.tsp.test.b.alpha ; com.tsp.test.b.beta ; com.tsp.test.b.release
So when the match checking is does, my application crash with the message error
Caused by: java.lang.RuntimeException: ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE string not set to applicationId
at com.microsoft.office.sfb.appsdk.Application.initialize(Application.java:110)
at com.microsoft.office.sfb.appsdk.Application.getInstance(Application.java:144)
at com.tsp.test.RootActivity.onCreate(RootActivity.java:89)
Of course, because com.tsp.test doesn't match com.tsp.test.a.alpha (or any other APK).
How can I achieve a dynamic resValue depending on the build variant selected that match the right application package name ?
EDIT :
To explain a bit more. First I choose the Build Variants as follow :
Customer : A
Version : Alpha
Then, in my RootActivity#onCreate() (my launcher activity), I start to configure the SfbSDK with an application instance depending on the SfbSDK :
this.mApplication = com.microsoft.office.sfb.appsdk.Application.getInstance(this.getApplication().getApplicationContext());
Somewhere in getInstance() method, the SfbSDK do an equals() between the context.getPackageName() and context.getString(string.ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE);
So, for debug, in my RootActivity#onCreate() I just wrote this two lines
String whatIWant = this.getPackageName(); // give me *com.tsp.test.a.alpha*
String whatIGet = this.getString(R.string.ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE); // give me *com.tsp.test*
This doesn't match ! So in SfbSDK the condition wasn't passed.
Well, thanks to Radesh and this link he provided to me, I've found my solution.
I removed resValue from the defaultConfig block then I added a new block in the android plugin task, that create the resValue for each variant.
apply plugin: 'com.android.application'
...
android {
...
defaultConfig {
applicationId "com.tsp.test"
...
}
...
flavorDimensions("customer", "version")
productFlavors {
a {
dimension "customer"
applicationIdSuffix ".a"
}
b {
dimension "customer"
applicationIdSuffix ".b"
}
alpha {
dimension "version"
applicationIdSuffix ".alpha"
}
beta {
dimension "version"
applicationIdSuffix ".beta"
}
release {
dimension "version"
applicationIdSuffix ".release"
}
}
...
applicationVariants.all { variant ->
variant.resValue "string", "ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE", "\"${applicationId}\""
}
}
...
This generate correctly the resValue with the package name of the selected variant.
For variant customer A and version Alpha, I get resValue = com.tsp.test.a.alpha.
you must declear variable ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE in gradle.properties like below
//default
org.gradle.jvmargs=-Xmx1536m
ENTERPRISE_AUTHENTICATOR_ACCOUNT_TYPE=xxx

How do I include `applicationIdSuffix` in some generated resource value?

Imagine this setup:
android {
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
productFlavors {
foo {
applicationId defaultConfig.applicationId + '.foo'
}
}
}
How can I set up a dynamic string value such as
resValue "string", "package_name", applicationId
so that it includes the applicationIdSuffix for debug builds?
If I add this to defaultConfig, its my defaultConfig's applicationId that is set. If I add this to the flavor configuration, it is missing the applicationIdSuffix (this is null at this level).
Any hints?
The cool part about applicationIdSuffix is that you can use it in flavors as well as in build types. Check this out:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "dev.bmax.suffixtext"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix '.debug'
}
}
productFlavors {
prod {
applicationIdSuffix '.prod'
}
mock {
applicationIdSuffix '.mock'
}
}
}
Now, when I build my 'prodDebug' variant the final application ID is 'dev.bmax.suffixtext.prod.debug', which is what you want if I understand your question correctly.
EDIT
You can access the variant's name in a Gradle task like this:
applicationVariants.all { variant ->
// Use 'variant.name'
}
Gradle Android Plugin version 0.14.3 added support of the variant specific BuildConfigField/resValue:
applicationVariants.all { variant ->
variant.resValue "string", "name", "value"
}

Get gradle build type in product flavor

I need to create different app names depending on the product flavour used.
While this was easy by simply setting a string resource, I can no longer do that because when the app is uploaded to hockeyapp the app name is set as '#string/app_name' instead of the value of app_name.
I have made some progress by setting the label in the manifest to be '${applicationName}' and setting the value with
manifestPlaceholders = [ applicationName : appName ];
in the product flavour block so that the value gets set at compile time.
The problem comes when I try to append the build type to the application name. I can't seem to find a way to know what build type is currently being used within the product flavour.
This is a stripped down version of the build for readability
android {
buildVersionName "1.0.0
buildTypes {
release {
... nothing special
}
uat {
signingConfig signingConfigs.debug
buildType = "uat"
applicationIdSuffix = "." + buildType
}
debug {
signingConfig signingConfigs.debug
buildType = "uat"
applicationIdSuffix = "." + buildType
}
}
productFlavors{
flavor1{
def appName = "app name " + buildType;
manifestPlaceholders = [ applicationName : appName ];
applicationId [id]
def clientIteration = [client iteration]
versionName buildVersionName + clientIteration
versionCode [version code]
}
flavor2{
... same as above with different app name
}
flavor3{
... same as above with different app name
}
}
}
This code works fine except the variable 'buildType' is always the last buildtype (in this case debug) which means the app name always has debug on the end.
Probably worth noting that I don't need to have anything appended on the end of the app name for releases.
You can append the values like this
android {
productFlavors {
Foo {
applicationId "com.myexample.foo"
manifestPlaceholders = [ appName:"Foo"]
}
Bar {
applicationId "com.myexample.bar"
manifestPlaceholders = [ appName:"Bar"]
}
}
buildTypes {
release {
manifestPlaceholders = [ appNameSuffix:""]
}
debug {
manifestPlaceholders = [ appNameSuffix:".Debug"]
applicationIdSuffix ".debug"
}
}
}
and in the manifest
<application
android:label="${appName}${appNameSuffix}"
...
</application>
If you want to access different values based on build type you can do it like this
buildTypes {
debug{
buildConfigField "String", "Your_string_key", '"yourkeydebugvalue"'
buildConfigField "String", "SOCKET_URL", '"some text"'
buildConfigField "Boolean", "LOG", 'true'
}
release {
buildConfigField "String", "Your_string_key", '"yourkeyreleasevalue"'
buildConfigField "String", "SOCKET_URL", '"release text"'
buildConfigField "Boolean", "LOG", 'false'
}
}
And to access those values using build variants:
if(!BuildConfig.LOG)
// do something with the boolean value
Or
view.setText(BuildConfig.yourkeyvalue);
I know I'm a bit late for the party but if you want different names based on the flavours, you should have something like this:
productFlavors{
flavour 1 {
applicationId "your_app_id"
resValue "string", "app_name", "Flavour 1 app name"
.......
}
flavour 2 {
applicationId "your_app_id"
resValue "string", "app_name", "Flavour 2 app name"
.......
}
}
and in your AndroidManifest.xml:
android:label="#string/app_name"
Hope this helps.
This link http://inaka.net/blog/2014/12/22/create-separate-production-and-staging-builds-in-android/ may help you out.
If you have two productFlavors (Production and Staging, for instance)
You should create two different resource folders:
project/app/src/production/res/values/strings.xml
<resources>
<string name="root_url">http://production.service.com/api</string>
</resources>
project/app/src/staging/res/values/strings.xml
<resources>
<string name="root_url">http://staging.service.com/api</string>
</resources>
You should add this following code inside the android {}:
productFlavors {
production {
applicationId "com.inaka.app.production"
}
staging {
applicationId "com.inaka.app.staging"
}
}
It's a good idea to have different icons for different productFlavors, just add the icon inside each different resource folder.

Categories

Resources