Filters

Android Basic Integration

Steps for basic integration of the Branch Android SDK into your mobile app.

This page outlines the steps required to integrate the Branch Android SDK. At the end, you will be ready to send Branch Events and use Branch Deep Links.

GitHubSDK SizeSpeedMin. OS Version
Repo~187kb for all featuresMedian 80ms to 250msAPI Level 21+

1. Configure Branch Dashboard

Start by configuring the Branch Dashboard for your application.

  1. Configure the default link settings for your app within the Configuration page of the Branch Dashboard.

  2. On the same page, confirm the "I have an Android App" and "Enable App Links" options are both selected. Fill in the values for "Android URI Scheme" and "Custom URL" based on your app.

  3. Also enter your SHA256 Cert Fingerprint, using all caps for the characters.

2. Install Branch

To install Branch, import the Branch Android SDK into your app-level build.gradle (Groovy) or build.gradle.kts (Kotlin), noting the REPLACE code comments where you need to add your app's values:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.example.android" // REPLACE with your app ID
        minSdkVersion 16
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
	// Required for all Android apps:
	implementation 'io.branch.sdk.android:library:5.8.0' // Check for latest version before hard-coding
  
	implementation 'store.galaxy.samsung.installreferrer:samsung_galaxystore_install_referrer:4.0.0'
      
	// Required if your app is in the Google Play Store (tip: avoid using bundled play services libs):
	implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
	// Alternatively, use the following lib for getting the AAID:
	// implementation 'com.google.android.gms:play-services-ads:17.2.0'
}
import java.util.*

plugins {
	id("com.android.application")
	kotlin("android")
}

dependencies {
	implementation(project(":Branch-SDK"))
	implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
	implementation("com.huawei.hms:ads-identifier:3.4.62.300")

	implementation("com.android.billingclient:billing:6.0.1")
	implementation("com.huawei.hms:ads-installreferrer:3.4.39.302")
	implementation("store.galaxy.samsung.installreferrer:samsung_galaxystore_install_referrer:4.0.0")
	implementation("com.miui.referrer:homereferrer:1.0.0.7")

	androidTestImplementation("androidx.test.ext:junit:1.1.5")
	androidTestImplementation("androidx.test:runner:1.5.2")
	androidTestImplementation("androidx.test:rules:1.5.0")
	androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

android {
	val ANDROID_BUILD_SDK_VERSION: String by project
	val ANDROID_BUILD_TARGET_SDK_MINIMUM: String by project
	val ANDROID_BUILD_TARGET_SDK_VERSION: String by project
	val VERSION_NAME: String by project
	val VERSION_CODE: String by project

	compileSdk = ANDROID_BUILD_SDK_VERSION.toInt()
	defaultConfig {
		applicationId = "io.branch.branchandroidtestbed" // REPLACE with your app ID
		minSdk = ANDROID_BUILD_TARGET_SDK_MINIMUM.toInt()
		targetSdk = ANDROID_BUILD_TARGET_SDK_VERSION.toInt()
		versionName = VERSION_NAME
		versionCode = VERSION_CODE.toInt()

		testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
	}

	val propFile = file("signing.properties")
	val props = if (propFile.exists()) {
		val props = Properties()
		props.load(propFile.inputStream())
		props
	} else {
		null
	}

	if (props != null) {
		val pStoreFile = props["STORE_FILE"] as? String
		val pStorePassword = props["STORE_PASSWORD"] as? String
		val pKeyAlias = props["KEY_ALIAS"] as? String
		val pKeyPassword = props["KEY_PASSWORD"] as? String
		if (!pStoreFile.isNullOrBlank()
			&& !pStorePassword.isNullOrBlank()
			&& !pKeyAlias.isNullOrBlank()
			&& !pKeyPassword.isNullOrBlank()
		) {
			signingConfigs {
				create("release") {
					storeFile = file(pStoreFile)
					storePassword = pStorePassword
					keyAlias = pKeyAlias
					keyPassword = pKeyPassword
				}
			}
		}
	}

	buildTypes {
		release {
			signingConfig = signingConfigs.findByName("release")
		}
	}
	namespace = "io.branch.branchandroidtestbed" // REPLACE with your namespace
}

Make sure you are using the latest version of io.branch.sdk.android:library by checking the version here.

3. Add Dependencies

At this stage, you can add certain dependencies to your Android app that will enable additional Branch Android SDK functionality.

Note: Some of these dependencies are already bundled into the Branch Android SDK.

DependencyDescriptionSignatureLibrary Repository
Android Advertising ID (AAID)In order for Branch to properly access the GAID value of a device, apps targeting Android 13+ will need to use the latest version
of the play-services-ads-identifier dependency or explicitly declare <uses-permission android:name="com.google.android.gms.permission.AD_ID" /> within the app's manifest file.
implementation "com.google.android.gms:play-services-ads-identifier:18.0.1"maven { url 'https://maven.google.com/' }
Play Install Referrer LibraryAs of version 4.3.0, Google's Play Install Referrer Library is bundled into Branch Android SDK.

If you are using a version below 4.3.0, you must update your app's dependencies to include the Play Install Referrer Library.
implementation "com.android.installreferrer:installreferrer:2.2"maven { url 'https://maven.google.com/' }
Huawei Mobile Services & Ads KitThe Branch SDK supports Huawei devices without Google Mobile Services. This dependency will add Install Referrer support on the Huawei AppGallery store and attribution using OAID.

Ensure proguard rules are set.
implementation "com.huawei.hms:ads-identifier:3.4.39.302"maven { url 'http://developer.huawei.com/repo/' }
Xiaomi GetApps Store ReferrerThis dependency will add Install Referrer support on the Xiaomi GetApps store.

Please reach out to your Xiaomi representative for additional details.
implementation "com.miui.referrer:homereferrer:1.0.0.6"maven { url 'https://repos.xiaomi.com/maven/‘ }
Samsung Galaxy Store ReferrerThis dependency will add Install Referrer support on the Samsung Galaxy store

Please reach out to your Samsung representative for additional details.
implementation "store.galaxy.samsung.installreferrer:samsung_galaxystore_install_referrer:4.0.0"Please reach out to your Samsung representative for the maven repo to add to your project level build.gradle

4. Configure App

To configure your app to use the Branch Android SDK, you will need to update your AndroidManifest.xml file.

To populate the file with the correct values, you will need to gather your:

  • App package name
  • Android URI scheme
  • The app.link domain associated with your app
  • The -alternate.app.link domain associated with your app
  • Branch Live Key
  • Branch Test Key

You can find these values for your app in your Branch Dashboard App Settings and Link Settings.

Use the sample code below for your AndroidManifest.xml file, making sure to replace every value that has a REPLACE comment associated with it:

<?xml version="1.0" encoding="utf-8"?>
<manifest
	xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android">
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>

	<!-- REPLACE `android:name` with your app's package name -->
	<application
      		android:allowBackup="true"
      		android:name="com.example.android.CustomApplicationClass" 
      		android:icon="@mipmap/ic_launcher"
      		android:label="@string/app_name"
      		android:supportsRtl="true"
      		android:theme="@style/AppTheme">

		<!-- Launcher Activity to handle incoming Branch intents -->
		<activity
        		android:name=".LauncherActivity"
        		android:launchMode="singleTask"
        		android:label="@string/app_name"
        		android:theme="@style/AppTheme.NoActionBar"
        		android:exported="true">

			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>

			<!-- Branch URI Scheme -->
			<intent-filter>
				<!-- If utilizing $deeplink_path please explicitly declare your hosts, or utilize a wildcard(*) -->
				<!-- REPLACE `android:scheme` with your Android URI scheme -->
				<data android:scheme="yourapp" android:host="open" />
				<action android:name="android.intent.action.VIEW" />
				<category android:name="android.intent.category.DEFAULT" />
				<category android:name="android.intent.category.BROWSABLE" />
			</intent-filter>

			<!-- Branch App Links - Live App -->
			<intent-filter android:autoVerify="true">
				<action android:name="android.intent.action.VIEW" />
				<category android:name="android.intent.category.DEFAULT" />
				<category android:name="android.intent.category.BROWSABLE" />
				<!-- REPLACE `android:host` with your `app.link` domain -->
				<data android:scheme="https" android:host="example.app.link" />
				<!-- REPLACE `android:host` with your `-alternate` domain (required for proper functioning of App Links and Deepviews) -->
				<data android:scheme="https" android:host="example-alternate.app.link" />
			</intent-filter>

			<!-- Branch App Links - Test App -->
			<intent-filter android:autoVerify="true">
				<action android:name="android.intent.action.VIEW" />
				<category android:name="android.intent.category.DEFAULT" />
				<category android:name="android.intent.category.BROWSABLE" />
				<data android:scheme="https" android:host="example.test-app.link" />
				<!-- REPLACE `android:host` with your `-alternate` domain (required for proper functioning of App Links and Deepviews) -->
				<data android:scheme="https" android:host="example-alternate.test-app.link" />
			</intent-filter>
		</activity>

		<!-- Branch init -->
		<!-- REPLACE `BranchKey` with the value from your Branch Dashboard -->
		<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_XXX" />
		<!-- REPLACE `BranchKey.test` with the value from your Branch Dashboard -->
		<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_XXX" />
		<!-- Set to `true` to use `BranchKey.test` -->
		<meta-data android:name="io.branch.sdk.TestMode" android:value="false" />

	</application>
	<queries>
		<intent>
			<action android:name="android.intent.action.SEND" />
			<data android:mimeType="text/plain" />
		</intent>
	</queries>
</manifest>

🚧

Single Task Launch Mode & Activities

The Single Task mode instantiates the Main/Splash Activity only if it does not exist in the Activity Stack.

If the Activity exists in the background, every subsequent intent to the Activity just brings it to the foreground. You can read more about Single Task mode here.

If your app has multiple activities triggered by multiple intent filters with the same scheme, your app may run into a race condition when clicking on links that open the app (ex. Branch Links and custom deep links). To prevent this, make sure to implement the Branch Android SDK in the LauncherActivity.

5. Load Branch

To load Branch, import io.branch.referral.Branch and use the getAutoInstance() method in your CustomApplicationClass:

package com.example.android

import android.app.Application
import io.branch.referral.Branch

class CustomApplicationClass : Application() {
    override fun onCreate() {
        super.onCreate()

        // Branch logging for debugging
        Branch.enableLogging()

       // Branch object initialization
        Branch.getAutoInstance(this)
    }
}
package com.example.android;

import android.app.Application;
import io.branch.referral.Branch;

public class CustomApplicationClass extends Application {
    @Override
    public void onCreate() {
        super.onCreate();

        // Branch logging for debugging
        Branch.enableLogging();

        // Branch object initialization
        Branch.getAutoInstance(this);
    }
}

To learn more about the getAutoInstance() and getInstance() methods, visit our Android SDK Full Reference guide.

6. Initialize Branch

To initialize Branch, add the following code to your LauncherActivity:

package com.example.android

import io.branch.indexing.BranchUniversalObject
import io.branch.referral.Branch
import io.branch.referral.BranchError
import io.branch.referral.util.LinkProperties

import android.util.Log;
import org.json.JSONObject;

// Always initialize Branch in `onStart()` - see warnings below for details
override fun onStart() {
	super.onStart()
	Branch.sessionBuilder(this).withCallback { branchUniversalObject, linkProperties, error ->
		if (error != null) {
			Log.e("BranchSDK_Tester", "branch init failed. Caused by -" + error.message)
		} else {
			Log.i("BranchSDK_Tester", "branch init complete!")
			if (branchUniversalObject != null) {
				Log.i("BranchSDK_Tester", "title " + branchUniversalObject.title)
				Log.i("BranchSDK_Tester", "CanonicalIdentifier " + branchUniversalObject.canonicalIdentifier)
				Log.i("BranchSDK_Tester", "metadata " + branchUniversalObject.contentMetadata.convertToJson())
			}
			if (linkProperties != null) {
				Log.i("BranchSDK_Tester", "Channel " + linkProperties.channel)
				Log.i("BranchSDK_Tester", "control params " + linkProperties.controlParams)
			}
		}
	}.withData(this.intent.data).init()
}

override fun onNewIntent(intent: Intent?) {
	super.onNewIntent(intent)
	this.setIntent(intent);
	if (intent != null && intent.hasExtra("branch_force_new_session") && intent.getBooleanExtra("branch_force_new_session",false)) {
		Branch.sessionBuilder(this).withCallback { referringParams, error ->
			if (error != null) {
				Log.e("BranchSDK_Tester", error.message)
			} else if (referringParams != null) {
				Log.i("BranchSDK_Tester", referringParams.toString())
			}
		}.reInit()
	}
}
package com.example.android;

import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

import org.json.JSONObject;

import io.branch.indexing.BranchUniversalObject;
import io.branch.referral.Branch;
import io.branch.referral.BranchError;
import io.branch.referral.util.LinkProperties;

public class LauncherActivity extends AppCompatActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_launcher);
	}

	@Override
	protected void onStart() {
		super.onStart();
		Branch.sessionBuilder(this).withCallback(new Branch.BranchUniversalReferralInitListener() {
			@Override
			public void onInitFinished(BranchUniversalObject branchUniversalObject, LinkProperties linkProperties, BranchError error) {
				if (error != null) {
					Log.e("BranchSDK_Tester", "branch init failed. Caused by -" + error.getMessage());
				} else {
					Log.i("BranchSDK_Tester", "branch init complete!");
					if (branchUniversalObject != null) {
						Log.i("BranchSDK_Tester", "title " + branchUniversalObject.getTitle());
						Log.i("BranchSDK_Tester", "CanonicalIdentifier " + branchUniversalObject.getCanonicalIdentifier());
						Log.i("BranchSDK_Tester", "metadata " + branchUniversalObject.getContentMetadata().convertToJson());
					}

					if (linkProperties != null) {
						Log.i("BranchSDK_Tester", "Channel " + linkProperties.getChannel());
						Log.i("BranchSDK_Tester", "control params " + linkProperties.getControlParams());
					}
				}
			}
		}).withData(this.getIntent().getData()).init();
	}

	@Override
	public void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		this.setIntent(intent);
		if (intent != null && intent.hasExtra("branch_force_new_session") && intent.getBooleanExtra("branch_force_new_session",false)) {
			Branch.sessionBuilder(this).withCallback(new BranchReferralInitListener() {
				@Override
				public void onInitFinished(JSONObject referringParams, BranchError error) {
					if (error != null) {
						Log.e("BranchSDK_Tester", error.getMessage());
					} else if (referringParams != null) {
						Log.i("BranchSDK_Tester", referringParams.toString());
					}
				}
			}).reInit();
		}
	}
}

🚧

LauncherActivity vs Other Activities

Branch recommends initializing the session inside the LauncherActivity. This is the Activity that contains the intent filter android.intent.category.LAUNCHER in your AndroidManifest.xml file.

However, if your app requires it, session initialization can happen in a different Activity too, as long as that Activity is the one configured to open Branch Links using the intent filters in AndroidManifest.xml.

Note that in this case, if the app is opened organically, Branch will auto-initialize behind the scenes and calling sessionBuilder()…init() will return an error. This is because the SDK will already be initialized. The main exceptions are push notifications and intra-app linking.

🚧

Always Initialize Branch in onStart()

Initializing Branch in other Android lifecycle methods, like onCreate() or onResume(), will lead to unintended behavior. The onStart() method is what makes the Activity visible to the user, as the app prepares for the Activity to enter the foreground and become interactive.

To learn more, visit:

If your app requires a different session initialization setup, please see the Delay Branch Initialization section of our Android Advanced Features guide.

7. Configure ProGuard

To collect the Google Advertising ID, you must ensure that ProGuard doesn't remove the necessary Google Ads class.

The surest way to do this is add it to your ProGuard rules. If your Application is enabled with ProGuard, add the following instruction to your proguard.cfg or proguard-rules.pro file:

-keep class com.google.android.gms.** { *; }

If you are adding support for Huawei devices without Google Mobile Services, please make sure to add the following to your ProGuard rules:

-keep class com.huawei.hms.ads.** { *; }
-keep interface com.huawei.hms.ads.** { *; }