In this article by Juwal Bose, author of the book LibGDX Game Development Essentials, we will learn how to use all those features that Google has to offer. Google provides AdMob (Google Mobile Ads) to display ads to monetize our game. Google Analytics can be used to track basic app data. Google Play services can be used to implement and track global leaderboards and achievements. Before we start implementing all of these, we need to ensure the following points:
- Use the SDK manager to update to the latest Android SDK tools
- Download and install Google Play services via the SDK manager
(For more resources related to this topic, see here.)
Interfacing platform-specific code
This chapter deals with an Android project, and much of what we will do will be specific to that platform. We need a way to detect the currently running platform to decide whether to invoke these features or not. Hence, we add a new public Boolean variable, isAndroid, in the ThrustCopter class, which is false by default. We can detect ApplicationType using the following code in the create method:
switch (Gdx.app.getType()) { case Android: isAndroid=true; break; case Desktop: break; case WebGL: break; case iOS: break; default: }
Now, we can check whether the game is running on an Android device using the following code:
if(game.isAndroid){ ... }
From the core project, we need to call the Android main class to invoke Android-specific code. We enable this using a new interface created in the core project: IActivityRequestHandler. Then, we make sure our AndroidLauncher main class implements this interface as follows:
public class AndroidLauncher extends AndroidApplication implements IActivityRequestHandler{ ... initialize(new ThrustCopter(this), config);
Note that we are passing this as a parameter to ThrustCopter, which provides a reference to the implemented interface. As this is Android-specific, other platforms’ start classes can pass null as an argument, as we will only use this parameter on the Android platform. In the ThrustCopter class, we save the reference with the name handler, as shown in the following code:
public ThrustCopter(IActivityRequestHandler IARH) { handler=IARH; ...
Visit https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code for more information.
Implementing Google Analytics tracking
The default implementation of Google Analytics will automatically provide the following information about your app: the number of users and sessions, session duration, operating systems, device models, and geography. To start off, we need to create a Google Analytics property and app view. Go ahead and start using Google Analytics by accessing it at https://www.google.com/analytics/web/?hl=en. Create a new account and select Mobile app and fill in the details. Once all details are entered, click on Get Tracking ID to generate a new tracking ID. The tracking ID will be unique for each account.
The Google Analytics version may change in future, which means the way they are integrated may also change. Check out the Google developers portal for details at https://developers.google.com/analytics/devguides/collection/android/v4/.
The AndroidManifest file needs to have the following permissions and the minSdkVersion instance should be set to 9, as follows:
<uses-sdk android_minSdkVersion="9" android_targetSdkVersion="23" /> <uses-permission android_name="android.permission.INTERNET" /> <uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
Have a look at the following Google Analytics registration form:
Copy the library project at <android-sdk>/extras/google/google_play_services/libproject/google-play-services_lib/ to the location where you maintain your Android app projects. Import the library project into your Eclipse workspace. Click on File, select Import, select Android, click on Existing Android Code Into Workspace, and browse to the copy of the library project to import it. This step is important for all the Google-related services that we are about to integrate. We need to refer to this library project from our Thrust Copter-android project. Right-click on the Thrust Copter-android project and select Properties. Select the Android section, which will display a blank Library section to the right. Click on Add… to select our library project and add it as a reference.
Adding tracker configuration files
We can provide configuration files to create Analytics trackers. Usually, we need only one tracker, which is usually called the global tracker, to report the basic analytics data. We add the global_tracker.xml file to the res/xml folder in the Android project. Copy this file from the source provided. Update the ga_trackingId section with the new tracking ID you got on creating your application entry on the Google Analytics site. The screenName section consists of the different scenes that will be tracked. We added the MenuScene and ThrustCopterScene classes to the screenName section. This needs to be changed for each game as follows:
<screenName name="com.csharks.thrustcopter.ThrustCopterScene">Thrust Copter Game</screenName> <screenName name="com.csharks.thrustcopter.MenuScene">Thrust Copter Menu</screenName>
Once the tracker XML file is in place, add the following element to the Android Manifest application part:
<meta-data android_name="com.google.android.gms.analytics.globalConfigResource" android_resource="@xml/global_tracker" />
We need to access the tracker and report activity start, stop, and scene changes. This can be done using the following code in the AndroidLauncher class:
Tracker globalTracker;
Then, add the following code within the onCreate method:
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this); globalTracker=analytics.newTracker(R.xml.global_tracker);
Now, we will move on to reporting. We added a new function in the IActivityRequestHandler interface called setTrackerScreenName(String path), which needs to be implemented as well:
@Override protected void onStart(){ super.onStart(); GoogleAnalytics.getInstance(this).reportActivityStart(this); } @Override public void onStop() { super.onStop(); GoogleAnalytics.getInstance(this).reportActivityStop(this); } @Override public void setTrackerScreenName(String path) { globalTracker.setScreenName(path); globalTracker.send(new HitBuilders.AppViewBuilder().build()); }
We also need to report screen names as well when we switch scenes. We do this within the constructors of MenuScene and ThrustCopterScene as follows:
if(game.isAndroid){ game.handler.setTrackerScreenName("com.csharks.thrustcopter.MenuScene"); }
It’s time to test whether everything is working. Connect your Android device and run our Android project on it. We can see that the analytics reporting is showing up in logcat. Once we have significant data, we can access the Google Analytics Web interface to analyze how the game is being played by the masses.
Adding Google Mobile Ads
Legacy AdMob is being renamed Google Mobile Ads, which is now linked with Google AdSense. First, we need to set up AdMob to serve ads by visiting https://www.google.com/ads/admob/index.html. Click on the Monetize section and use the Add your app manually option to set up a new banner ad. This will allot a new AdMob ad unit ID. The Ads API is also part of the Google Play services platform that we have already integrated into our Android project. We have already added as follows the necessary permissions to AndroidManifest, but we need to add the following as well:
<!--This meta-data tag is required to use Google Play Services.--> <meta-data android_name="com.google.android.gms.version" android_value="@integer/google_play_services_version" /> <!--Include the AdActivity configChanges and theme. --> <activity android_name="com.google.android.gms.ads.AdActivity" android_configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android_theme="@android:style/Theme.Translucent" />
AdMob needs its own view, whereas LibGDX creates its own view when initializing. A typical way of coexisting will be our Game view in fullscreen with the Ad view overlaid. We will use RelativeLayout to arrange both views. We need to replace the initialize method with the initializeForView method, which lacks some functionality; we need to specify those manually. The onCreate method of the AndroidLauncher class has the following new code:
requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); RelativeLayout layout = new RelativeLayout(this); View gameView = initializeForView(new ThrustCopter(this), config); layout.addView(gameView); // Add the AdMob view RelativeLayout.LayoutParams adParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); adParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); adParams.addRule(RelativeLayout.CENTER_HORIZONTAL); adView = new AdView(this); adView.setAdSize(AdSize.BANNER); adView.setAdUnitId(AD_UNIT_ID); startAdvertising(); layout.addView(adView, adParams); setContentView(layout);
The startAdvertising function is as follows:
private void startAdvertising() { AdRequest adRequest = new AdRequest.Builder().build(); adView.loadAd(adRequest); }
The IActivityRequestHandler class has a new method, showAds(boolean show), that toggles the visibility of the adView instance. The method is implemented as follows:
@Override public void showAds(boolean show) { handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS); }
Here, handler, which is used to access adView from the thread that created it, is initialized as follows:
private final int SHOW_ADS = 1; private final int HIDE_ADS = 0; protected Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch(msg.what) { case SHOW_ADS: { adView.setVisibility(View.VISIBLE); break; } case HIDE_ADS: { adView.setVisibility(View.GONE); break; } } } };
For more information, visit https://github.com/libgdx/libgdx/wiki/Admob-in-libgdx.
Alternatively, runOnUiThread can be used instead of the handleMessage method. Now, we can show ads in the menu and hide it when we switch to the game.
Summary
In this article, you learned how to handle platform-specific code and you also learned how to use Google Play services to integrate AdMob and Analytics.
Resources for Article:
Further resources on this subject:
- Scaling friendly font rendering with distance fields [article]
- Sparrow iOS Game Framework – The Basics of Our Game [article]
- Animations in Cocos2d-x [article]