I want to create an application with two flavours one with less features and one with more. How can i do it
Let us suppose there is
A - application
Flavour1 - feature1, feature2
Flavour2 - feature1, feature2, feature3
How to release one apk
and how user will install the application from play store how the user will know which flavour is going to be installed
There is nice documentation from google.
Multiple flavours
You should declare the flavors in the buildfile
android {
...
defaultConfig {...}
buildTypes {...}
productFlavors {
demo {
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
}
full {
applicationIdSuffix ".full"
versionNameSuffix "-full"
}
}
}
After build two apk files will be created. They have different application id so you can publish them as two different applications to the Play Store. For example one free and one paid.
Features
There can be more solutions but the simplest one is to use buildConfigField.
productFlavors {
demo {
applicationIdSuffix ".demo"
versionNameSuffix "-demo"
buildConfigField "boolean", "FEATURE_1", "true"
buildConfigField "boolean", "FEATURE_2", "false"
buildConfigField "boolean", "FEATURE_3", "false"
}
full {
applicationIdSuffix ".full"
versionNameSuffix "-full"
buildConfigField "boolean", "FEATURE_1", "true"
buildConfigField "boolean", "FEATURE_2", "true"
buildConfigField "boolean", "FEATURE_3", "true"
}
}
Then in java source code you can check if features are enabled:
if (BuildConfig.FEATURE_1) {
//run feature
}
Some othe approaches are described in the documentation.
Related
I'm building an Android app with React Native and I have troubles configuring some of my API key.
I have one of my API key in my Gradle.properties
RNGP_ANDROID_API_KEY=mysupersecretkey
And I have two different flavor: beta for testing and prod for production.
I would like to override the RNGP_ANDROID_API_KEY in my two flavors
Like this:
flavorDimensions 'env'
productFlavors {
beta {
dimension 'env'
applicationId "com.fake.package"
signingConfig signingConfigs.release
manifestPlaceholders=[google_api:"beta_key"]
}
prod {
dimension 'env'
applicationId "com.fake.package"
signingConfig signingConfigs.release
manifestPlaceholders=[google_api:"prod_key"]
}
}
It works well to override value in the manifest but I don't know how to change the Gradle.properties value.
Please let me know what I can do!
Instead of writing in Gradle.properties
Try to use it as below,
flavorDimensions 'env'
productFlavors {
beta {
dimension 'env'
applicationId "com.fake.package"
signingConfig signingConfigs.release
manifestPlaceholders=[google_api:"beta_key"]
buildConfigField 'String', 'RNGP_ANDROID_API_KEY', '"mysupersecretkey"'
}
prod {
dimension 'env'
applicationId "com.fake.package"
signingConfig signingConfigs.release
manifestPlaceholders=[google_api:"prod_key"]
buildConfigField 'String', 'RNGP_ANDROID_API_KEY', '"mysupersecretkey"'
}
}
You can access this variable by BuildConfig.RNGP_ANDROID_API_KEY
I built an app and registered it with Firebase as part of a project that includes three other apps. Here's what my buildTypes in the app gradle build file looks like:
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "int", "RULE_DEBUG_LEVEL", "0"
}
releaseDebuggable {
debuggable true
buildConfigField "int", "RULE_DEBUG_LEVEL", "1"
}
debug {
//applicationIdSuffix '.debug'
versionNameSuffix " Debug"
buildConfigField "int", "RULE_DEBUG_LEVEL", "1"
}
and the productFlavors are as follows:
flavorDimensions "fmplus"
productFlavors {
String name = "fmplus"
fmplus {
name = "fmplus"
applicationId getPackageName(name)
resValue 'string', 'app_name', getAppName(name)
resValue 'color', 'accent', getThemeColor(name)
resValue 'color', 'accentDark', getThemeColorDark(name)
}
fmplus_nab_htc_one_m8 {
name = "fmplus"
applicationId getPackageName(name)
applicationIdSuffix ".nab_htc_one_m8"
versionNameSuffix "-nab_htc_one_m8"
resValue 'string', 'app_name', getAppName(name)
resValue 'color', 'accent', getThemeColor(name)
resValue 'color', 'accentDark', getThemeColorDark(name)
}
fmplus_nyx_supraim_sn10 {
name = "fmplus"
applicationId getPackageName(name)
applicationIdSuffix ".nyx_supraim_sn10"
versionNameSuffix "-nyx-supraim-sn10"
resValue 'string', 'app_name', getAppName(name)
resValue 'color', 'accent', getThemeColor(name)
resValue 'color', 'accentDark', getThemeColorDark(name)
}
changeFileManifest(name)
}
Another programmer on our team handled the flavor labelled 'fmplus_nyx_supraim_sn10' and I'm doing 'fmplus_nab_htc_one_m8'. Both apps appear in Firebase under the same project, but Firebase reports his events but not mine. I've been struggling with this for some time now and have run out of ideas. Does anyone have an idea what I'm doing wrong. And yes, I downloaded and installed the google-services.json file and rebuilt the app before running it, just like the docs say.
The problem was in the app gradle file: Android Studio 3.0 requires a default dimensions statement, which I have, but what I also needed to do was add a dimension statement to the build flavor in question. The other developer, whose app didn't have this problem, was using Studio 2.3.3.
i want to publish a paid app and free app
i have created flavor of free and paid using this code
productFlavors {
free {
applicationId "com.example.myapp.free"
versionName "1.0-free"
// this boolean can be accessed in java classes by using BuildConfig class
// and now you can identify if your app is the paid version or not
buildConfigField "boolean", "PAID_VERSION", "false"
}
paid {
applicationId "com.example.myapp.paid"
versionName "1.0-paid"
buildConfigField "boolean", "PAID_VERSION", "true"
}
}
I want to know how can upload this app
we need two diffretnt apk for that (paid relese apk and free apk)
or single apk
i need both variant available in playstore
If You have two flavor variant
like
Free with package name as
applicationId "com.example.myapp.free"
Paid with package name as
applicationId "com.example.myapp.paid"
Both are different applicationId so you need to upload in two different apps in play store, Because your applicationId is a playstore app id So it must be a unique
or
You have to remove this line in both flavor and use common applicationId
then
handle like this following way
defaultConfig {
applicationId "com.example.myapp"
}
productFlavors {
free {
versionName "1.0-free"
buildConfigField "boolean", "PAID_VERSION", "false"
buildConfigField "String", "BuildType", "Free"
}
paid {
versionName "1.0-paid"
buildConfigField "boolean", "PAID_VERSION", "true"
buildConfigField "String", "BuildType", "Paid"
}
}
Handle in java code
public void manageFeaturesWithBuildType()
{
String buildType = BuildConfig.BuildType;
if(buildType.equals("Paid"))
{
//Here Enable or Disable your features for paid Build
}
else
{
//Here Enable or Disable your features for free Build
}
}
You got this type of Build variant as shown in image: In your case you can see paidDebug and freeDebug option.
If you want to release paid version then you have to select paidDebug and if you want to release free version then you have to select freeDebug.
The resValue method (or whatever it's called) allows you to set a resource value in buildTypes or productFlavors. Is there a corresponding way to get a resource value that was set by resValue?
It appears that productFlavors is evaluated before buildTypes, so a resValue set in buildTypes takes precedence. I want to append "Debug" to the app name in debug builds, but I need to get the value that was set in the product flavor in order to append to it.
Edit: I tried Marcin KoziĆski's suggestion to use a variable, but all product flavors are evaluated before any build type. Therefore, this does not work:
android {
String appName = ""
productFlavors {
Foo {
appName = "Foo"
}
Bar {
appName = "Bar"
}
}
buildTypes {
release {
resValue "string", "app_name", appName
}
debug {
resValue "string", "app_name", appName + " Debug"
}
}
}
In buildTypes, appName always has the value from the last product flavor. So in this example, all builds receive the name "Bar" or "Bar Debug".
Basically, I need a resValueSuffix analogous to applicationIdSuffix. Apparently no such animal exists. Does the com.android.application plugin expose anything that I could use to achieve this?
If you are only trying to set the App Label (or other manifest values) you can solve this with manifest placeholders.
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"
}
}
}
Then in your Android Manifest you simply use both placeholders for your app name (or other values)
<application
android:label="${appName}${appNameSuffix}"
...
</application>
This allow you to install all 4 variants side by side on a single device as well as give them different names in the app drawer / launcher.
EDIT 11/22/2019
Updated how placeholders values are set based on feedback from #javaxian
You can check the build variants like this
Define values in gradle
buildTypes {
debug{
buildConfigField "String", "Your_string_key", '"yourkeyvalue"'
buildConfigField "String", "SOCKET_URL", '"some text"'
buildConfigField "Boolean", "LOG", 'true'
}
release {
buildConfigField "String", "Your_string_key", '"release text"'
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);
To have an alternative version of a resource in debug builds you can use the debug source set.
strings.xml can be found under following path src/main/res/values, which means it's in the main source set. If you create a new directory src/debug/res/values you can put a new strings.xml file in there with values that should be overridden in debug builds. For example:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My Application Debug</string>
</resources>
This will replace whatever value app_name has in your main file. You don't have to duplicate all the strings in here - ones you don't include here are simply taken from the main file.
This question already has an answer here:
Is there a way to have a common section with buildConfigField and resValue in gradle?
(1 answer)
Closed 7 years ago.
I have a number of flavors in my app, and I want to set a boolean buildConfigField for a subset of them. Is there a way to avoid having to add the field to every flavor? Ideally my build.gradle would look like the following:
productFlavors {
flavor1 {
}
....
flavor4 {
buildConfigField "boolean", "DISABLE_SOMETHING", "true"
}
flavor5 {
buildConfigField "boolean", "DISABLE_SOMETHING", "true"
}
....
flavor8 {
}
}
So in my app I can just go
if (BuildConfig.DISABLE_SOMETHING) {
//disable stuff
}
However, compilation fails when I try to build with, for example, flavor1, as it can't find the field. I don't want to have to remember to add this to every new flavor I create. Are there any ways around this?
You can use defaultConfig for this (inside android{})
defaultConfig {
buildConfigField "boolean", "DISABLE_SOMETHING", "true"
}