I have an android app in use by several clients, when I build the app currently I have 2 options 1. release and 2. debug
Now my problem is some om my clients require certain features others do not, meaning that for the same app some features might be disabled for some clients while other clients would have extra features.
I would like to know how I can have more than one release option when building my app. eg.
ClientARelease
ClientBRelease
ClientCRelease
ClientADebug
ClientBDebug
ClientCDebug
So if Client A wants all features of the app but client B does not when I select ClientBRelease the features not required by ClientB are not bundled with the apk.
How do I achieve this with android?
You should use Android Build Types and Build Flavors. Check out Android Developer Guide
Each build variant represents a different version of your app that you can build. For example, you might want to build one version of your app that's free, with a limited set of content, and another paid version that includes more. You can also build different versions of your app that target different devices, based on API level or other device variations.
Creating product flavors is similar to creating build types: add them
to the productFlavors block in your build configuration and include
the settings you want.
In some cases, you may want to combine configurations from multiple
product flavors. For example, you may want to create different
configurations for the "full" and "demo" product flavors that are
based on API level. To do this, the Android plugin for Gradle allows
you to create multiple groups of product flavors as flavor dimensions.
When building your app, Gradle combines a product flavor configuration
from each flavor dimension you define, along with a build type
configuration, to create the final build variant.
Also for some cases you can use APK splitting/AppBundle.
Related
I want to integrate firebase analytics to both of my android and iOS app.
For android, I have a single flavour with 3 different build types. Dev staging and release. All these build types have the same application ID.
For historical reasons, I cannot change the build type to include a different suffix to differentiate.
On firebase analytics, I would like to have two dashboard! The first to include data from dev and staging. The second to include data from release.
The question is - how should I create the projects and link the google-service.json? Is that possible to do?
Thanks.
Inside src directory create different directories for each build type. Then place google-services.json for specific types inside the respective directories.
For example I have two build types debug and release, so this is how it works
So you will have three directories - dev, staging and release and they will have their own google-services.json file.
I have an application with three different flavours and two build types. The main module defines some common interfaces and each flavour implements them. The flavours correspond to stores : google, amazon and samsung. The app proposes some in-app purchases, which is specific to each flavour.
I implemented a few debug classes to ease the integration tests of the google the flavour. The debug classes implement the IInAppBillingService and an alternative to the purchase dialog. Now the problem is that some debug classes have dependencies on a flavour. I can't switch to another flavour without having compilation errors.
I would like to keep these test classes, as they are used in integration tests. Also, they should be kept away from the release build type, to avoid any debug/testing code appearing in the released version.
My question is : how to define classes with dependencies on a flavour, but that are not used during the building of the release version ?
As you probably know, you can put code and assets specific to a flavor in its own folder under src. For example you can have folders such as google, amazon, and samsung for each flavor. You can also create debug and release folders for classes and assets specific to each build type. This is useful if you have code only used for development but that should not go into the final release version.
You can take this a step further and create folders for any combination of build type and flavor, for example, googleDebug or amazonRelease.
For automated testing, create a test folder for unit tests which run locally on you development machine or an androidTest folder for instrumented tests run on a device or emulator. These can also be combined with build types and flavors, for example androidTestDebug, androidTestSamsung, or androidTestSamsungDebug.
All classes for testing should go under
Instead of having the classes that handles the billing logic in the flavour folder directly, I used another module specific to a flavour.
In the google billing module, I keep all the classes involved in the in-app purchases. Each module specific to a flavour is imported for the corresponding flavour. This way, I avoid mixing code specific to different flavours.
For example, in the build.gradle file I have :
googleCompile project(path: ':inappbilling_google')
In the inappbilling_google module, I have all the classes involved in in-app purchase through Google in-app billing. There is a debug folder to keep all the classes that should not appear during the release build process.
I was quite happy with this solution, as I keep clearly separate the code of the different flavours and build types... until I discovered that Gradle had some limitations. Indeed, the code present in the debug folder of modules is not included during the compilation. This is a known issue (limitation) of Gradle and the Android Gradle plugin.
However, the Google team and Gradle team have worked on this and have announced a solution to this, with the version 2.5 of the Android Gradle plugin.
In a near future, it will be possible to separate our code using the Android Gradle plugin only. Good news !
I have followed Google's official doc for creating multiple APKs for different API levels. (I know it is not recommended to have different APKs, however in my specific case I must use it).
The only difference between the two APKs in my case would only the AndroidManifest.xml files content. While reading through the official doc which recommends creating a shared library between two different apps modules, I wondered whether it is going to be possible to achieve the same through different flavors in Gradle's build setting, specifying a different AndroidManifest.xml file for each flavor and thus generating two APKs with different manifests (the idea came from this post).
Since creating two flavors is much simpler (time and maintenance wise), and my only need is two different manifests files, isn't this a better option than the suggest common library module shared between two different app modules?
You should check about Product flavors
A product flavor defines a customized version of the application build
by the project. A single project can have different flavors which
change the generated application.
Structure
android {
productFlavors {
dev {
applicationId "root.com.android.dev"
}
product {
applicationId "root.com.android"
}
}
}
You can read also
Product flavors in Android Studio for hermetic testing
I am using various services in my android app for which I need userIDs and keys. Now I can store all of the keys in my string.xml file. However, since I have two different environments (production and debug) in server, i need to figure out a way of maintaining two different sets of keys based on environment.
Is there a standard way of maintaining keys for android app ?
You are looking for gradle feature called build variants. This will let you have i.e. different string.xml for release build and different for debug ones. See docs:
https://developer.android.com/tools/building/configuring-gradle.html
Build variants are specific builds that you can produce from Gradle,
based around shared core source code. While a standard app may have a
debug and release build type, you can expand on this by adding flavor
dimensions.
Read official guideline about Configuring Gradle Builds
Using Gradle Build Variants
I worked with iPhone Xcode Traget to create multiple iPhone apps with single code base. My question, is it possible to create multiple targets for Android project. If yes, is it possible with Eclipse?
Edit:
Xcode Target: A single Projects can contain one or more targets, each of which produces one product (App). This has always only one Project in which we can select the specific target and run desired app
iPhone have only one Project for many products (App1, App2, App3 etc), Now can I have same as this, one Android Project and multiple products (App1, App2, App3 etc)
Thanks in advance
A bit late, but for those who still looking for solution:
Gradle Build System uses a Build Variant and combination of product flavors to generate different apps with shared/common code base and resources.
As per Android Developer Reference Site:
The build system uses product flavors to create different product versions of your app. Each product version of your app can have different features or device requirements. The build system also uses build types to apply different build and packaging settings to each product version. Each product flavor and build type combination forms a build variant. The build system generates a different APK for each build variant of your app.
Now one can have two or more product flavors e.g (paid flavor, free/demo flavor) etc for one single project with same code base.
For more information See Build Variants & Product Flavors Doc
After a wide research I realized Android Library Project will provide solution for my requirement
An Android library project is a development project that holds
shared Android source code and resources. Other Android application
projects can reference the library project and, at build time, include
its compiled sources in their .apk files. Multiple application
projects can reference the same library project and any single
application project can reference multiple library projects.
Note: You need SDK Tools r14 or newer to use the new library project
feature that generates each library project into its own JAR file. You
can download the tools and platforms using the Android SDK and AVD
Manager, as described in Adding SDK Components.
• If you have source code and resources that are common to multiple
Android projects, you can move them to a library project so that it is
easier to maintain across applications and versions. Here are some
common scenarios in which you could make use of library projects:
• If you are developing multiple related applications that use some of
the same components, you move the redundant components out of their
respective application projects and create a single, reuseable set of
the same components in a library project. If you are creating an
application that exists in both free and paid versions. You move the
part of the application that is common to both versions into a library
project. The two dependent projects, with their different package
names, will reference the library project and provide only the
difference between the two application versions.
There is only one build target in android in a single project. Backword compatibility is controlled at install time using minSdkVersion, targetSdkVersion and maxSdkVersion in the manifest file
http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
Also android market make sure that if your app has native code and is built for ARM architecture it is not visible on a x86 device
You can control what version someone has installed and starting one activity or another depending on that. You can use something like this:
private static boolean version= android.os.Build.VERSION.SDK_INT>=android.os.Build.VERSION_CODES.HONEYCOMB;
And then do something like:
public void onCreate(Bundle savedInstanceState){
Intent startActivity =null;
if(version)
startActivityIntent = new Intent( this, newVersionActivity.class );
else
startActivityIntent = new Intent( this, oldVersionActivity.class );
finish();}
This example is from a video of the Google I/O (min 5~): http://www.google.com/events/io/2011/sessions/android-protips-advanced-topics-for-expert-android-app-developers.html.
So you are supposed to specify the minSdkVersion and the maxSdkVersion and then control what which activity to start.