Monthly Archives: September 2017

Build Version increment with Gradle build script

Check out Lines Galaxy Android game to view the results in action.

Make your Gradle build script handle the apk version for you!

Your second Google Play Console release will most certainly end at the APK upload. This would probably be caused by the fact that the APK build version was not incremented.

Yes, this was also my case. I was like whaaat? what version? ooh nooo…

Have no worries. I searched for a way which would handle the build version number automatically. I also wanted to allow the developer to manage certain properties of the version. The solution which I came to works pretty nice for my needs and probably yours if you’re reading this.

The build scripts are also handling two types of releases: beta (debug) and production.

Each version has its own API keys, features enabled/disabled, application ids, icons and names. This is what I needed but after a certain point having custom properties for each release type will be a piece of cake.

Customizing the Gradle script to handle build version

First of all you’ll need a way to store the current version. This file should be included in the versioning system. Let’s call it build.properties. Place the file in your android folder and add these contents:

VERSION_NUMBER=1
VERSION_BUILD=0
VERSION_PATCH=0

Obviously the version_number should start with 1. This value and version_patch will be automatically incremented each time you’ll do an assembleRelease.

When you upload an APK each version should be higher than the previous uploaded one.

Version_build will be incremented which each build and is mainly for debug.

Next thing we need to handle is the gradle script. The followind script is added in android task.

android {
    ...

    // read the current state of the build version properties
    def buildPropertiesFile = file('build.properties')
    def value = 0

    // the major and minor properties need to be manually incremented by the dev
    // the resulting version could be used for identifying the apk on Google Play Console
    def versionMajor = 1
    def versionMinor = 0

    if(!buildPropertiesFile.canRead()) {
        throw new GradleException("Could not read build.properties")
    }

    // load the properties from the file
    def Properties buildProperties = new Properties()
    buildProperties.load(new FileInputStream(buildPropertiesFile ))

    // we only want to increment the number and patch for release builds
    // you'll need to check the exact name of the build task - it might be assembleRelease (without android:)
    def runTasks = gradle.startParameter.getTaskNames()
    if('android:assembleRelease' in runTasks || 'android:assembleProductionRelease' in runTasks) {
        value = 1;
    }

    def versionNumber = buildProperties['VERSION_NUMBER'].toInteger() + value
    def versionPatch = buildProperties['VERSION_PATCH'].toInteger() + value
    def versionBuild = buildProperties['VERSION_BUILD'].toInteger() + 1
    
    buildProperties['VERSION_NUMBER'] = versionNumber.toString()
    buildProperties['VERSION_PATCH'] = versionPatch.toString()
    buildProperties['VERSION_BUILD'] = versionBuild.toString()

    // save the build state
    versionProps.store(buildPropertiesFile.newWriter(), null)

    defaultConfig {
        applicationId "com.example.name"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode versionNumber
        versionName "${versionMajor}.${versionMinor}.${versionPatch}.${versionBuild}"
    }
    productFlavors {
        beta {
            applicationIdSuffix ".beta"
            versionNameSuffix "-SNAPSHOT" + getDate()
        }
        production {
        }
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFile 'proguard-project.txt'
            applicationVariants.all { variant ->
                variant.outputs.each { output ->
                    def SEP = "_"
                    def flavor = variant.productFlavors[0].name
                    def buildType = variant.variantData.variantConfiguration.buildType.name
                    def version = variant.versionName
                    def date = new Date();
                    def formattedDate = date.format('ddMMyy_HHmm')

                    def apkName= applicationId+SEP+flavor+SEP+buildType+SEP+version+SEP+formattedDate+".apk"

                    output.outputFile = new File(output.outputFile.parent, apkName)
                }
            }
        }
    }
    ...
}

That’s it! Your apk build version will now be handled automatically so you can focus on what’s important.

My other Android posts could be of interest to you! Check them out or check out Lines Galaxy Android game to view the results in action.

How to integrate Rewarded Video Ad in LibGDX

Check out Lines Galaxy Android game to view the results in action.

What is Rewarded Video Ad?

Rewarding users with different in-app coins or features can be done using Rewarded Video Ad.

This might be an advertising solution that could be accepted by users whilst supporting the development of a free mobile application.

Most games tend to place the user in a situation where he is stuck or he needs some coins in order to unlock a certain feature.

The user is then given the possibility to tap a button or an element which will open a full screen video.

At the end of this video called Rewarded Video Ad the player will receive his prize.

Let’s get started with Rewarded Video Ad!

Integrating Rewarded Video Ads in LibGDX is quite easy.

You’ll need to import a few packages (AndroidLauncher.java):

import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;

public class AndroidLauncher extends AndroidApplication implements GoogleServices, RewardedVideoAdListener {
    private RewardedVideoAd adRewardedVideoView;
    private static final String REWARDED_VIDEO_AD_UNIT_ID = "ca-app-pub-3940256099942544/5224354917";
    private VideoEventListener vel;
}

Our Android Launcher has one member which will store the RewardedVideoAd object.

Initialing the Rewarded Video Ad requires an ad unit. The one in this example contains a test value provided by AdMob.

While developing the application this is the unit id that you should use.

As soon as you’re ready to deploy into production you can switch to your real unit id obtained from AdMob website.

The vel member will be used for sharing Rewarded Video Ads events in other classes.

Next thing we need is to initiate the Rewarded Video Ad, to set the event listener and to start loading the first video so it will be ready when we need it (AndroidLauncher.java):

public void loadRewardedVideoAd() {
    adRewardedVideoView.loadAd(REWARDED_VIDEO_AD_UNIT_ID, new AdRequest.Builder().build());
}

public void setupRewarded() {
    adRewardedVideoView = MobileAds.getRewardedVideoAdInstance(this);
    adRewardedVideoView.setRewardedVideoAdListener(this);
    loadRewardedVideoAd();
}

Above code does not need any extra explications. Method names have been carefully chosen so they’re quite self explanatory.
While using Rewarded Video Ads we’ll need a way to know if the video is loaded and if it’s not loaded we need to load it.
In our Android Launcher class we’ll add a new private boolean is_video_ad_loaded (AndroidLauncher.java).

public boolean hasVideoLoaded(){
    if(is_video_ad_loaded) {
        return true;
    }
    runOnUiThread(new Runnable() {
        public void run() {
            if (!adRewardedVideoView.isLoaded()) {
                loadRewardedVideoAd();
            }
        }
    });
    return false;
}

Following method will show the add if it’s loaded or load an new ad (AndroidLauncher.java).

public void showRewardedVideoAd(){
    runOnUiThread(new Runnable() {
        public void run() {
            if (adRewardedVideoView.isLoaded()) {
                adRewardedVideoView.show();
            } else {
                loadRewardedVideoAd();
            }
        }
    });
}

The Android Launcher is the class that initiates your application and you should only have the code for this purpose here.

You’ll want to interact with the Rewarded Video Ad instance and one way of doing this is to implement some interfaces.

In my code there’s GoogleServices interface which looks like this (GoogleServices.java):

public interface GoogleServices {
    public boolean hasVideoLoaded();
    public void loadRewardedVideoAd();
    public void showRewardedVideoAd();
    public void setVideoEventListener(VideoEventListener listener);
}

Again not many details are required here. The VideoEventListener is another interface which only handles the Rewarded Video Ad events (VideoEventListener.java):

public interface VideoEventListener {
    void onRewardedEvent(String type, int amount);
    void onRewardedVideoAdLoadedEvent();
    void onRewardedVideoAdClosedEvent();
}

I only needed handlers for these events in my other classes but you can customize it for your needs.

We’ll need some handlers for the above events: (Android Launcher.java):

@Override
public void onRewarded(RewardItem reward) {
    if(vel != null) {
        // The type and the amount can be set in your AdMob console
        vel.onRewardedEvent(reward.getType(), reward.getAmount());
    }
}

// Each time the video ends we need to load a new one
@Override
public void onRewardedVideoAdClosed() {
    is_video_ad_loaded = false;
    loadRewardedVideoAd();
    if(vel != null) {
        vel.onRewardedVideoAdClosedEvent();
    }
}

@Override
public void onRewardedVideoAdLoaded() {
    if(vel != null) {
        vel.onRewardedVideoAdLoadedEvent();
    }
    is_video_ad_loaded = true;
}

Once this is added you can now attach the video event listener (AndroidLauncher.java):

public void setVideoEventListener (VideoEventListener listener) {
    this.vel = listener;
}

This is all the needed setup.
Last thing we need to do is initiate the Rewarded Video Ad in our onCreate method (AndroidLauncher.java):

@Override
protected void onCreate (Bundle savedInstanceState) {
    ...
    View gameView = initializeForView(new App(this), config);
    setupRewarded();
    ...
}

That’s all! The integration is now finished!

You can now use the Rewarded Video Ad in your applications classes (App.java):

public class App extends Game implements VideoEventListener {

    public GoogleServices googleServices;

    public App(GoogleServices googleServices) {

        this.googleServices = googleServices;
        this.googleServices.setVideoEventListener(this);

        // this probably should not be here but it's how you show the video
        if(this.googleServices.hasVideoLoaded()) {
            this.googleServices.showRewardedVideoAd();
        }

   }

    @Override
    public void onRewardedEvent(String type, int amount) {
        // player has just finished the video and was rewarded
    }

    @Override
    public void onRewardedVideoAdLoadedEvent() {
        // video is ready and can be presented to the player
    }

    @Override
    public void onRewardedVideoAdClosedEvent() {
        // player has closed the video so no reward for him
    }

}

Checkout my other LibGDX posts or Lines Galaxy Android game to view the results in action.