Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Build Flavors with and without Ads (new Google Developer Policy)

I have published an App with 2 Build Flavors: a "normal" version including ads and an ad-free-version.

In the Google Play Developer Console you now have to mark your App if it uses Ads. This is ok for the normal version but the ad-free-version uses the same dependencies as the pro version (especially google play services). So I get a warning when I set this version to ad-free because ad-libs were found.

Is it possible to change dependencies depending on gradle build flavor?

build.gradle:

android {
   (...)
   productFlavors {
        lite {
            signingConfig signingConfigs.Release
            versionCode 14
            versionName '1.1.5'
            buildConfigField "boolean", "IS_PRO", "false"
        }
        pro {
            applicationId 'com.example.exampleadfree'
            signingConfig signingConfigs.Release
            targetSdkVersion 21
            versionCode 14
            versionName '1.1.5'
            buildConfigField "boolean", "IS_PRO", "true"
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:support-v4:21.0.3'
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.android.support:cardview-v7:21.0.2'
    compile 'com.google.android.gms:play-services:6.1.+'
    compile project(':libraries:SharedItems')
    compile 'com.android.support:recyclerview-v7:21.0.2'
}
like image 204
Jörn Buitink Avatar asked Nov 20 '15 07:11

Jörn Buitink


2 Answers

You can change

compile 'com.google.android.gms:play-services:6.1.+'

to

liteCompile 'com.google.android.gms:play-services:6.1.+'

and that will include the play services lib with your lite version only.

But you are not done, because now the code in your app that creates the AdView and related classes from the play services library will not compile when you create the pro version.

My solution in a similar situation (with the billing library) was to move all the code that refers to the excluded library and related classes to a source file which is also only built with the lite flavor, and then provide a dummy implementation for the pro version that does not refer to the library.

For example, create two flavor-specific src directories with the same-named java class in each:

src/lite/java/com/example/myapp/util/AdUtil.java
src/pro/java/com/example/myapp/util/AdUtil.java

In the lite version of AdUtil, you can make calls to google play services and get an AdView to return:

View getAdView(...)
{
    View adView = new AdView(...);
    adView.setAdSize(...);
    adView.setAdUnitId(...);
    ...
    return adView;
}

And in the pro version of that class, you can just put a dummy implementation that does not refer to the play services lib:

View getAdView(...)
{
    return null;
}

Then in your main app code, when you call AdUtil.getAdView(), you will get a View in the lite version which you can place on the screen. In the pro version you will get a null so you skip adding the view (but you are likely already checking if you are pro or lite before trying to create the adview in the first place).

like image 61
Doug Simonton Avatar answered Oct 05 '22 22:10

Doug Simonton


When a project declares Product Flavors, these extends the main configuration.

From here. So Product Flavors effectively adds new configurations for every flavor your declare. In gradle it is possible to add dependencies that are specific to a configuration. For example,

dependencies {
    <configname> <dependency>
}

If you want to list all the configurations that your project has added:

configurations.findAll().each{println "$it.name"}

In the case if your project you'll see configs that are named the same as your product flavors. So as @cwbowron commented, to add a compile-time dependency for flavor lite:

dependencies {
    liteCompile <dependency>
}
like image 28
RaGe Avatar answered Oct 05 '22 22:10

RaGe