I am currently developing my first Android application ever, and it is the Android/Kotlin version of an iOS application I already developed. I created 3 different Firebase projects to have independent realtime database instances for each environment:
com.myapp.debug is only used by me for development
com.myapp.beta should be used for alpha and beta testing
com.myapp should be only for the production application that will be released publically on the Play Store
When I was looking into plugging these 3 environments in my Android app, I read that I should use product flavors for that, so here is how I configured my build:
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.derbigum.approofreferences"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "dev", "qa", "prod"
productFlavors {
dev {
dimension "dev"
applicationId "com.derbigum.approofreferences.debug"
}
qa {
dimension "qa"
applicationId "com.derbigum.approofreferences.beta"
}
prod {
dimension "prod"
applicationId "com.derbigum.approofreferences"
}
}
}
And of course I created the corresponding subfolders in src to store the various versions of google-services.json I got for each project.
I did all my development with that and it worked so far: development data was created in the right database.
But now I want to do a first closed alpha release but I'm confused as to how I should generate my APK. I have only 2 build variants:
devQaProdDebug
devQaProdRelease
Maybe I made a mistake in configuring flavorDimensions? Maybe it's something else. Can someone please help me figure out if my setup is OK, and if so how I should go about building the closed alpha version of my app and release it to my internal users for testing?
I think what you want here is not three dimensions for three environments, but just one dimension for environment, with three flavors:
flavorDimensions "env"
productFlavors {
dev {
dimension "env"
applicationId "com.derbigum.approofreferences.debug"
}
qa {
dimension "env"
applicationId "com.derbigum.approofreferences.beta"
}
prod {
dimension "env"
applicationId "com.derbigum.approofreferences"
}
}
This will get you build variants for each environment.
Related
Is it possible to change the package name of an Android application using Gradle?
I need to compile two copies of the same app, having a unique package name (so I can publish to the market twice).
As a simpler alternative to using product flavours as in Ethan's answer, you can also customise build types.
How to choose between the approaches:
If you need different package names to be able to have both debug and release apks installed on a device, then use the build type approach below, as Gradle plugin docs agree. In this case flavours are an overkill. (I think all projects should by default do this, as it will make life easier especially after you've published to the store and are developing new features.)
There are valid uses for product flavours, the typical example being an app with free and paid versions. In such case, check Ethan's answer and read the documentation too: Configuring Gradle Builds and Gradle Plugin User Guide.
(You can also combine the two approaches, which results in every build variant having distinct package name.)
Build type configuration
For debug build type, and all other non-release types, define applicationIdSuffix which will be added to the default package name.
(Prior to Android Gradle plugin version 0.11 this setting was known as packageNameSuffix.)
android {
buildTypes {
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
}
beta {
applicationIdSuffix '.beta'
versionNameSuffix '-BETA'
// NB: If you want to use the default debug key for a (non-debug)
// build type, you need to specify it:
signingConfig signingConfigs.debug
}
release {
// signingConfig signingConfigs.release
// runProguard true
// ...
}
}
}
Above, debug and release are default build types whose some aspects are configured, while beta is a completely custom build type. To build the different types, use assembleDebug, assembleBeta, etc, as usual.
Similarly, you can use versionNameSuffix to override the default version name from AndroidManifest (which I find very useful!). E.g. "0.8" → "0.8-BETA", as configured above.
Resources:
This example is straight from Xavier Ducrohet's "Google I/O 2013: The New Android SDK Build System" presentation.
Build Types in the User Guide.
Myself I've been using productFlavors so far for this exact purpose, but it seems build type customisation may be closer to my needs, plus it keeps the build config simpler.
Update (2016): I've since used this approach in all my projects, and I think it definitely is the way to go. I also got it included in Android Best Practices guide by Futurice.
You could so something like this
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
flavorDimensions "flavor1", "flavor2"
productFlavors {
flavor1 {
applicationId "com.example.flavor1"
versionCode 20
}
flavor2 {
applicationId "com.example.flavor2"
minSdkVersion 14
}
}
}
You can also change the field android.defaultConfig.applicationId if you want to do one-off builds.
Taken from: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-Flavor-Configuration
With the gradle plugin version of 1.0.0+ you have to use applicationId as stated in the migration guide
Renamed Properties in ProductFlavors
packageName => applicationId
Thus in your build.gradle you would now use:
productFlavors {
flavor1 {
applicationId "com.example.flavor1"
}
flavor2 {
applicationId "com.example.flavor2"
}
}
From Ethan's answer, both flavorGroups and packageName both are not available anymore. Below works as of March 2015.
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
flavorDimensions "flavor"
productFlavors {
flavor1 {
flavorDimension "flavor"
applicationId "com.example.flavor1"
versionCode 20
}
flavor2 {
flavorDimension "flavor"
applicationId "com.example.flavor2"
minSdkVersion 14
}
}
}
I did not want to use Flavors, so I found a way to do so with buildTypes. I did this by changing my app/build.gradle file as follows:
defaultConfig {
applicationId "com" // See buildTypes.type.applicationIdSuffix
...
}
...
buildTypes {
debug {
applicationIdSuffix ".domain.name.debug"
...
}
releaseStaging {
applicationIdSuffix ".compagny.staging"
...
}
release {
applicationIdSuffix ".domain.name"
...
}
}
This allows me to have 3 apps next to each other on my devices.
I hope this helps others.
I am working on updating an Android app using Android Studio 3. The previous versions where created using Android Studio 2.
When I build the last version using Android Studio 2 two separate APKs have been created, one for each product flavor I configured. Now in Android Studio 3 the "Generate Signed APK" dialog only offers a "combined" flavor which creates a single APK containing both flavors:
App Gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.example.MyApp"
minSdkVersion 14
targetSdkVersion 26
versionCode 42
versionName "2.0.1"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
flavorDimensions "freemium", "free"
productFlavors {
MyApp {
dimension "freemium"
}
MyAppFree {
dimension "free"
applicationId 'com.example.MyApp.Free'
}
}
}
Select "Build/Generate Signed APK..." in Android Studio
Enter my keystore password and click Next
On the following page I can select the destination folder, the build type (release) and the flavors. While v2 offered both flavors here (MyApp and MyAppFree), v3 only offers MyApp-MyAppFree
app-MyApp-MyAppFree-release.apk is created instead of app-MyApp-release.apk and app-MyAppFree-release.apk
How to fix this?
Ok, the problem was caused by using different flavor dimensions for the two flavors. Gradle creates one assemble task for each dimension combination: MyAppMyAppFree in my case
I added the dimensions only to to silence the warning "All flavors must now belong to a named flavor dimension" when updating from Android Studio 2 to 3. Since I did not actually used the dimensions the solution was to simply use one dimension for both flavors:
flavorDimensions "default"
productFlavors {
MyApp {
dimension "default"
}
MyAppFree {
dimension "default"
applicationId 'com.example.MyApp.Free'
}
}
When I try to deploy with these productFlavors, wear debug apk won't built and it is not embedded into mobile release apk. But after I delete productFlavors from mobile and wear build.gradle file, it's working as it should.
productFlavors {
lite {
}
pro {
applicationId 'example.app.id.pro'
versionNameSuffix '.pro'
}
}
Try assigning applicationIdSuffix and versionNameSuffix values for each of your product flavors. See Configuration of Product Flavors for more information.
And if you haven't done yet, add publishNonDefault truein your Wear module's build.gradle file.
android {
publishNonDefault true
......
productFlavors {
trial {
applicationId "com.sample.myapp.trial"
versionName "3.0.1"
versionCode 301
}
full {
applicationId "com.sample.myapp"
versionName "3.0.1"
versionCode 301
}
}
}
See this related SO post and Packaging and Distributing Wear Apps for additional insights.
I have used build.gradle(app) to create different flavors of apk.
But installing different flavors of same apk overrides the previous one.
I want to create different apks to run on same device simultaneously.
I want to create different apk with different appicon which can be installed on same device and run simultaneously.
Any link or tutorial or direct help is appreciated.
Thanks in advance.
Change the PackageName of the flavor
Sample Gradle File
apply plugin: 'com.android.application'
android {
lintOptions {
abortOnError false
}
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 16
}
buildTypes {
debug {
minifyEnabled false
zipAlignEnabled true
}
release {
minifyEnabled true
zipAlignEnabled true
}
}
productFlavors {
Flavor1 {
applicationId "com.falvor.one" //This is where you change the package name
}
Flavor2 {
applicationId "com.falvor.two"
}
}
}
Flavor Hierarchy in Android
- src/main/java
- src/flavor1
--------------Java
----------------Your java files
--------------res
----------------Drawable
src/flavor2/java
For more understanding, follow this link
You need to create new productFlavors in your gradle file, like this;
productFlavors {
Flavor1 {
applicationId 'com.project.fl1'
signingConfig signingConfigs.xx
versionCode 1
}
Flavor2 {
applicationId 'com.project.fl2'
signingConfig signingConfigs.xx
versionCode 1
}
Flavor3 {
applicationId 'com.project.fl3'
signingConfig signingConfigs.xx
versionCode 1
}
}
The important thing here is to give each one a unique applicationId, they can then be installed on the same phone.
This post explains exactly how to achieve what you want step by step.
Most importantly:
add the product flavours container to the app build.gradle file
productFlavors {
free {
applicationId "antoniocappiello.com.buildvariantsexample.free"
}
paid {
applicationId "antoniocappiello.com.buildvariantsexample.paid"
}
}
create inside src a directory with the exact name of the product flavour that you want to look different from the main variant, for example with the configuration at step 1 the directory name could be paid or free . And inside that directory create the subfolder res/drawable where you are going to place your new app launcher icon.
Directory structure example
Is it possible to change the package name of an Android application using Gradle?
I need to compile two copies of the same app, having a unique package name (so I can publish to the market twice).
As a simpler alternative to using product flavours as in Ethan's answer, you can also customise build types.
How to choose between the approaches:
If you need different package names to be able to have both debug and release apks installed on a device, then use the build type approach below, as Gradle plugin docs agree. In this case flavours are an overkill. (I think all projects should by default do this, as it will make life easier especially after you've published to the store and are developing new features.)
There are valid uses for product flavours, the typical example being an app with free and paid versions. In such case, check Ethan's answer and read the documentation too: Configuring Gradle Builds and Gradle Plugin User Guide.
(You can also combine the two approaches, which results in every build variant having distinct package name.)
Build type configuration
For debug build type, and all other non-release types, define applicationIdSuffix which will be added to the default package name.
(Prior to Android Gradle plugin version 0.11 this setting was known as packageNameSuffix.)
android {
buildTypes {
debug {
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
}
beta {
applicationIdSuffix '.beta'
versionNameSuffix '-BETA'
// NB: If you want to use the default debug key for a (non-debug)
// build type, you need to specify it:
signingConfig signingConfigs.debug
}
release {
// signingConfig signingConfigs.release
// runProguard true
// ...
}
}
}
Above, debug and release are default build types whose some aspects are configured, while beta is a completely custom build type. To build the different types, use assembleDebug, assembleBeta, etc, as usual.
Similarly, you can use versionNameSuffix to override the default version name from AndroidManifest (which I find very useful!). E.g. "0.8" → "0.8-BETA", as configured above.
Resources:
This example is straight from Xavier Ducrohet's "Google I/O 2013: The New Android SDK Build System" presentation.
Build Types in the User Guide.
Myself I've been using productFlavors so far for this exact purpose, but it seems build type customisation may be closer to my needs, plus it keeps the build config simpler.
Update (2016): I've since used this approach in all my projects, and I think it definitely is the way to go. I also got it included in Android Best Practices guide by Futurice.
You could so something like this
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
flavorDimensions "flavor1", "flavor2"
productFlavors {
flavor1 {
applicationId "com.example.flavor1"
versionCode 20
}
flavor2 {
applicationId "com.example.flavor2"
minSdkVersion 14
}
}
}
You can also change the field android.defaultConfig.applicationId if you want to do one-off builds.
Taken from: http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-Flavor-Configuration
With the gradle plugin version of 1.0.0+ you have to use applicationId as stated in the migration guide
Renamed Properties in ProductFlavors
packageName => applicationId
Thus in your build.gradle you would now use:
productFlavors {
flavor1 {
applicationId "com.example.flavor1"
}
flavor2 {
applicationId "com.example.flavor2"
}
}
From Ethan's answer, both flavorGroups and packageName both are not available anymore. Below works as of March 2015.
android {
...
defaultConfig {
minSdkVersion 8
versionCode 10
}
flavorDimensions "flavor"
productFlavors {
flavor1 {
flavorDimension "flavor"
applicationId "com.example.flavor1"
versionCode 20
}
flavor2 {
flavorDimension "flavor"
applicationId "com.example.flavor2"
minSdkVersion 14
}
}
}
I did not want to use Flavors, so I found a way to do so with buildTypes. I did this by changing my app/build.gradle file as follows:
defaultConfig {
applicationId "com" // See buildTypes.type.applicationIdSuffix
...
}
...
buildTypes {
debug {
applicationIdSuffix ".domain.name.debug"
...
}
releaseStaging {
applicationIdSuffix ".compagny.staging"
...
}
release {
applicationIdSuffix ".domain.name"
...
}
}
This allows me to have 3 apps next to each other on my devices.
I hope this helps others.