Before i build android project to two different application paid and free.
I changed each values and strings so yesterday I made a big mistake.
So, I'm laerning how to use gradle to build my app.
My app have some differents.
app name (just add suffix '-Free') -> values/string.xml
change flag in my *.java
// signingConfigs is ommited.
productFlavors{
free{
packageName "my.app.free"
versionCode 20
signingConfig signingConfigs.freeConfing
copy{
from('/res'){
include '**/*.xml'
}
into 'build/res/'
filter{
String line -> line.replaceAll("android:label=\"@string/app_name\"", "android:label=\"@string/app_name_free\"")
}
}
copy{
from('/src'){
include '**/*.java'
}
into 'build/src/'
filter{
String line -> line.replaceAll("public static final Boolean IS_FULL_VER = true;", "public static final Boolean IS_FULL_VER = false;")
}
}
}
paid{
packageName "my.app.paid"
versionCode 20
signingConfig signingConfigs.paidConfing
}
}
but, built app changed nothing at all.
What i missed?
See the documentation on product flavors
:
http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Product-flavors
In your build.gradle
, in each flavor, you can define flags to be generated in your BuildConfig.java
file:
productFlavors {
free {
packageName "com.company.appfree"
buildConfig "public final static com.company.common.MonetizationType monetizationType = com.company.common.MonetizationType.FREE;"
}
paid {
packageName "com.company.apppaid"
buildConfig "public final static com.company.common.MonetizationType monetizationType = com.company.common.MonetizationType.PAID;"
}
}
This example uses an enum (that you need to define somewhere in your java code):
public enum MonetizationType {
PAID, FREE
}
You can now use this anywhere like this:
if (BuildConfig.monetizationType == MonetizationType.FREE) { ... }
For overriding resources, you can create different resource files in the source folders for each flavor:
Use the following structure
app/build.gradle
app/ [.. some other files...]
app/src/main/
app/src/main/java
app/src/main/res
app/src/main/assets
app/src/main/AndroidManifest.xml
app/src/free/res/values/apptitle.xml
app/src/paid/res/values/apptitle.xml
apptitle.xml would be a string resource file (just like strings.xml), but with only one string: the one you want to be different depending on the flavor.
(You don't need have a apptitle.xml in your main/res directory).
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_title">App Title (or whatever you want)</string>
</resources>
You might be able to override strings in different ways, but I like to keep the overridden strings separate from the rest for clarity.
The accepted answer is not working with the newer versions of Gradle.
You need to replace buildConfig
with buildConfigField
to get the same result:
productFlavors {
free {
packageName "com.company.appfree"
buildConfigField "com.company.common.MonetizationType", "MONETIZATION_TYPE", "company.common.MonetizationType.FREE"
}
paid {
packageName "com.company.apppaid"
buildConfigField "com.company.common.MonetizationType", "MONETIZATION_TYPE", "company.common.MonetizationType.PAID"
}
}
treesAreEverywhere's answer (as well as user name) is right on. But it's also very valuable to know that Android Studio will greatly simplify the process of creating build flavor or attribute specific resource files.
In the AS project window, right click on the res/values folder and select New > Values resource file. Then name it (e.g., "strings"), select the Source set if not the default, and select any desired qualifiers (e.g., Screen Width = 800). This is the easiest way to make sure you're putting your resource overrides where the compiler wants them.
This is how I did in my project. I created multiple build types instead of flavours. This solution will add a prefix to your package name based on what build type you are trying to assemble. For ex, for dev the package name will be com.sample.myapp.dev and similarly for beta package name will be changed to com.sample.myapp.release. You can tweak it to get Free and Paid prefixes. Hope it would help.
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.production
applicationIdSuffix '.release'
versionNameSuffix '-RELEASE'
}
dev {
signingConfig signingConfigs.debug
applicationIdSuffix '.dev'
versionNameSuffix '-DEV'
}
beta {
signingConfig signingConfigs.debug
applicationIdSuffix '.beta'
versionNameSuffix '-BETA'
}
debug {
signingConfig signingConfigs.debug
applicationIdSuffix '.debug'
versionNameSuffix '-DEBUG'
debuggable true
}
}