Setup
In this integration guide we will take you through the initial steps of instrumenting your game with the GameAnalytics Android SDK.
Download & Installation
Manual Installation
The first step is to download our SDK from here
Unzip the files and add all files inside the GA/jar folder your Android Studio project in the relative paths specified below (where NAME_OF_MODULE could be app
or the name of the module you have set): NAME_OF_MODULE/libs/gameanalytics.jar
Java library.
aar folder
Unzip the files and import the gameanalytics.aar
inside the GA/aar folder and import it by doing File->New->New Module…->Import .JAR/.AAR Package
Then select the .aar
file where you have downloaded it to and give it subproject name, like ‘gameanalytics’ for example.
Using Maven
Add this to your repositories (inside the project build.gradle):
maven { url 'https://maven.gameanalytics.com/release'; }
and add this to your dependencies (inside the app build.gradle):
// use latest version instead version number in this example
implementation 'com.gameanalytics.sdk:gameanalytics-android:+'
Configure Android Studio
To use the SDK in Android Studio follow the below steps:
- Install Google Play Services from the Android SDK manager (it is listed under the ‘Extra’ folder) and make sure to add its dependencies to the app module’s build.gradle and the app’s AndroidManifest.xml.
- Make sure compileSdkVersion is set to 33 in the app module’s build.gradle.
- Add permissions as seen in the code sample for AndroidManifest.xml (billing is only needed if IAP is used).
Setup build.gradle (using jar)
If you are using GameAnalytics as a .jar
, you will need to add the following code to your build.gradle
:
android {
compileSdkVersion 33
// (more Android stuff)
}
dependencies {
//... (other dependencies)
compile 'com.google.android.gms:play-services-base:10.2.1'
compile 'com.android.support:appcompat-v7:24.2.0'
//... (other dependencies)
}
Setup build.gradle (using aar)
If you are using GameAnalytics as an .aar
, you will need to add the following code to your build.gradle
:
android {
compileSdkVersion 33
// (more Android stuff)
}
dependencies {
//... (other dependencies)
compile project(':gameanalytics')
// assuming you have imported the aar and used 'gameanalytics' for its module name
compile 'com.android.support:appcompat-v7:24.2.0'
//... (other dependencies)
}
Maven Setup
In the project build.gradle file add the following to the repository section.
maven { url 'http://maven.gameanalytics.com/release'; }
In the same file you should make sure the following settings are at least supporting version 24 for your app.
compileSdkVersion 33
buildToolsVersion "34.0.0"
targetSdkVersion 33
In the application build.gradle file add the following to the dependencies section.
// use latest version instead version number in this example
compile 'com.gameanalytics.sdk:gameanalytics-android:3.4.2'
Using C++
If you want to use the native Android SDK from C++ code there is a C++ wrapper. The required files are all located under the cpp folder. It includes the wrapper library for various architectures which you need to link against and a header file which should be included in the code where you need to call the SDK functions from. Before you call any of the main functions you need to call either:
GameAnalyticsJNI.nativeSetContext(activity); // from java code
// or
gameanalytics::jni_setContext(activity); // from C++ code
You also need to place this inside your JNI_OnLoad
function:
gameanalytics::jni_setJavaVM(vm);
You must link against log and android libraries when building.
Storage Permissions
The SDK will use a database stored that can reach up to several MBs if the user keep being offline for longer periods of time while playing. When the user is back online it will attempt to send the events. Where the database is placed depends on permissions.
READ_EXTERNAL_STORAGE
and WRITE_EXTERNAL_STORAGE
permissions are optional.
If the user’s device has Android API level 19 (Kitkat) or above, the SDK will try use context.getExternalCacheDir() (if it exists) to store its internal database.
If the device is less than Android API level 19 (Kitkat) and if READ_EXTERNAL_STORAGE
and WRITE_EXTERNAL_STORAGE
permissions have been added the SDK will also try to use context.getExternalCacheDir()
If the none of the previous mentioned conditions have been met, then context.getCacheDir()
will be used for storage of the internal database.
Game Orientation
If your game can change orientation then each time the orientation changes it will cause the activity to destroy and be recreated. This will create a new session in the SDK. To avoid this it is very important to add the following line along with your activity entry in the AndroidManifest.xml
file.
android:configChanges="orientation|screenSize|keyboardHidden"
Here is an example of an activity entry inside the AndroidManifest.xml
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Add permission
Add the following permission, if it is not already present in your AndroidManifest.xml
file:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Remember that after Android 6.0 it might be necessary to request app permission if the Android OS has not already been altered to avoid it.
Using the plugin
Finally, in order to read IMEI and MEID values, you need to call GAImei.readImei()
before starting the SDK:
GAImei.readImei();
// ...
GameAnalytics.initializeWithGameKey(activity, "[game key]", "[secret key]");
You can call doNotReadImei()
to stop the SDK from reading IMEI and MEID values:
GAImei.doNotReadImei();
Proguard
If your app uses proguard you will have to add these rules to your proguard rules:
-keep class com.gameanalytics.sdk { *; }
-keep class com.gameanalytics.sdk.** { *; }
-keep class com.gameanalytics.sdk.GAPlatform { *; }
-keep class com.gameanalytics.sdk.GAPlatform.** { *; }
-keep class android.net.ConnectivityManager.** { *; }
-keep class com.google.android.instantapps.InstantApps { *; }
-keepclassmembers class com.google.android.instantapps.InstantApps { *; }
Using the SDK
Now we should be ready for adding code to activate the SDK!
The configuration and initialization steps should be called inside the onCreate method of the Activity (e.g. MainActivity.java
) class which is created first in the app.
Once steps 1 & 2 are done you can add events at different parts of the game code where some relevant action is happening.
Remember to import the GameAnalytics package whenever you need to call the SDK.
import com.gameanalytics.sdk.*;
Configuration
The available configuration options are:
- build
- available (allowed) custom dimensions
- available (allowed) resource currencies
- available (allowed) resource item types
Build
The build parameter is used to specify the current version of your game. Specify it using a string. It is recommended to use a 3 digit version like [major].[minor].[patch]
.
// Set build version
GameAnalytics.configureBuild("android 1.0.0");
Auto detect app version to use for build field
There is an option to auto detect app version to use for build field. Just call this before intializing the SDK:
GameAnalytics.configureAutoDetectAppVersion(true);
This is equivalent to doing this:
PackageManager pm = context.getPackageManager();
PackageInfo info = pm.getPackageInfo(context.getPackageName(), 0);
GameAnalytics.configureBuild(info.versionName);
User ID
The SDK will automatically generate a user id and this is perfectly fine for almost all cases.
Sometimes it is useful to supply this user_id manually – for example if you download raw data for processing and need to match your internal user id (could be a database index on your user table) to the data collected through GameAnalytics.
Note that if you introduce this into a game that is already deployed (using the automatic id) it will start counting existing users as new users and your metrics will be affected. Use this from the start of the app lifetime.
GameAnalytics.configureUserId("user1234567879");
Specifying Allowed Values
For certain types it is required to define a whitelist containing possible unique values during the configuration phase.
When the SDK is being used (after initialization) only the specified values will be allowed. A maximum of 20 values are allowed for each list.
Processing many unique dimension values can be taxing for our servers. A few games with a poor implementation can seriously increase our cost and affect stability. Games will be blocked if they submit too many unique dimension values. We have this configuration requirement to guide users into planning what dimension values can be used.
// Configure available virtual currencies and item types
GameAnalytics.configureAvailableResourceCurrencies("gems", "gold");
GameAnalytics.configureAvailableResourceItemTypes("boost", "lives");
// Configure available custom dimensions
GameAnalytics.configureAvailableCustomDimensions01("ninja", "samurai");
GameAnalytics.configureAvailableCustomDimensions02("whale", "dolphin");
GameAnalytics.configureAvailableCustomDimensions03("horde", "alliance");
Each resource currency string should only contain [A-Za-z] characters.
Event Submission
If you for GDPR purposes need to disable event submission you can call the following:
GameAnalytics.setEnabledEventSubmission(false);
By default event submission is of course enabled. You will still receive configs if you have set any for your game even after disabling event submission.
Initialization
To initialize the SDK you have two options:
1. With Activity
Since version 2.1.0 of the SDK we recommend that you call this function to initialize, using the apps main activity, and the game key and game secret for your game.
// Initialize
GameAnalytics.initializeWithGameKey(activity, "[game key]", "[secret key]");
2. Without Activity
Alternatively you can use this function to initialize the SDK, using the game key and game secret for your game.
// Initialize
GameAnalytics.initializeWithGameKey("[game key]", "[secret key]");
Using this approach you MUST call the following function inside your Activity class in the onCreate method, before calling any of the configuration functions and before calling initializeWithGameKey or any other GameAnalytics function:
GAPlatform.initializeWithActivity(this);
Don’t have any keys yet? Head over here and register your game at the GameAnalytics website!
Session
Once initialize is called it will start the first session and automatically handle session changes based on activity events. By default the session will start when the application initializes the sdk and when it goes in foreground, the session will end when the application closes or when it goes into background.
If for some reason you want to, you can manually manage your session. This can be enabled with the following method:
GameAnalytics.setEnabledManualSessionHandling(true);
After setting the manual session handling you will have to start the session yourself by calling the next method:
GameAnalytics.startSession();
And when you need to close the session, you will have to end the current session by calling:
GameAnaylytics.endSession();
By using manual session handling you will be responsible to decide when the session begins and ends, if not setup correctly it will result in inaccurate readings.
Below is a common example of the code placed in the main activity class:
package your.package.here;
import com.gameanalytics.sdk.GameAnalytics;
import com.gameanalytics.sdk.GAPlatform;
import com.gameanalytics.sdk.StringVector;
public class MainActivity extends Activity
{
// ... other code from your project ...
@Override
protected void onCreate(Bundle savedInstanceState)
{
// ... other code from your project ...
// Enable log
GameAnalytics.setEnabledInfoLog(true);
GameAnalytics.setEnabledVerboseLog(true);
// Configure available virtual currencies and item types
GameAnalytics.configureAvailableResourceCurrencies("gems", "gold");
GameAnalytics.configureAvailableResourceItemTypes("boost", "lives");
// Configure available custom dimensions
GameAnalytics.configureAvailableCustomDimensions01("ninja", "samurai");
GameAnalytics.configureAvailableCustomDimensions02("whale", "dolphin");
GameAnalytics.configureAvailableCustomDimensions03("horde", "alliance");
// Configure build version
GameAnalytics.configureBuild("0.1.0");
// Initialize
GameAnalytics.initializeWithGameKey(this, "[game key]", "[secret key]");
// ... other code from your project ...
}
// ... other code from your project ...
}