Android Advanced Features

Create Content Reference

BranchUniversalObject buo = new BranchUniversalObject()
        .setCanonicalIdentifier("content/12345")
        .setTitle("My Content Title")
        .setContentDescription("My Content Description")
        .setContentImageUrl("https://lorempixel.com/400/400")
        .setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
        .setLocalIndexMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
        .setContentMetadata(new ContentMetadata().addCustomMetadata("key1", "value1"));
val buo = BranchUniversalObject()
        .setCanonicalIdentifier("content/12345")
        .setTitle("My Content Title")
        .setContentDescription("My Content Description")
        .setContentImageUrl("https://lorempixel.com/400/400")
        .setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
        .setLocalIndexMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
        .setContentMetadata(ContentMetadata().addCustomMetadata("key1", "value1"))

Create Deep Link

LinkProperties lp = new LinkProperties()
        .setChannel("facebook")
        .setFeature("sharing")
        .setCampaign("content 123 launch")
        .setStage("new user")
        .addControlParameter("$desktop_url", "http://example.com/home")
        .addControlParameter("custom", "data")
        .addControlParameter("custom_random", Long.toString(Calendar.getInstance().getTimeInMillis()));

    buo.generateShortUrl(this, lp, new Branch.BranchLinkCreateListener() {
        @Override
        public void onLinkCreate(String url, BranchError error) {
            if (error == null) {
                Log.i("BRANCH SDK", "got my Branch link to share: " + url);
            }
        }
    });
 val lp = LinkProperties()
        .setChannel("facebook")
        .setFeature("sharing")
        .setCampaign("content 123 launch")
        .setStage("new user")
        .addControlParameter("$desktop_url", "http://example.com/home")
        .addControlParameter("custom", "data")
        .addControlParameter("custom_random", Long.toString(Calendar.getInstance().getTimeInMillis()))

    buo.generateShortUrl(this, lp, BranchLinkCreateListener { url?, error? ->
        if (error == null) {
            Log.i("BRANCH SDK", "got my Branch link to share: " + url)
        }
    })

Share Deep Link

LinkProperties lp = new LinkProperties()
        .setChannel("facebook")
        .setFeature("sharing")
        .setCampaign("content 123 launch")
        .setStage("new user")
        .addControlParameter("$desktop_url", "http://example.com/home")
        .addControlParameter("custom", "data")
        .addControlParameter("custom_random", Long.toString(Calendar.getInstance().getTimeInMillis()));

    ShareSheetStyle ss = new ShareSheetStyle(MainActivity.this, "Check this out!", "This stuff is awesome: ")
        .setCopyUrlStyle(ContextCompat.getDrawable(this, android.R.drawable.ic_menu_send), "Copy", "Added to clipboard")
        .setMoreOptionStyle(ContextCompat.getDrawable(this, android.R.drawable.ic_menu_search), "Show more")
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.FACEBOOK)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.EMAIL)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.MESSAGE)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.HANGOUT)
        .setAsFullWidthStyle(true)
        .setSharingTitle("Share With");

    buo.showShareSheet(this, lp,  ss,  new Branch.BranchLinkShareListener() {
        @Override
        public void onShareLinkDialogLaunched() {
        }
        @Override
        public void onShareLinkDialogDismissed() {
        }
        @Override
        public void onLinkShareResponse(String sharedLink, String sharedChannel, BranchError error) {
        }
        @Override
        public void onChannelSelected(String channelName) {
        }
    });
var lp = LinkProperties()
        .setChannel("facebook")
        .setFeature("sharing")
        .setCampaign("content 123 launch")
        .setStage("new user")
        .addControlParameter("$desktop_url", "http://example.com/home")
        .addControlParameter("custom", "data")
        .addControlParameter("custom_random", Long.toString(Calendar.getInstance().getTimeInMillis()))

    val ss = ShareSheetStyle(this@MainActivity, "Check this out!", "This stuff is awesome: ")
        .setCopyUrlStyle(resources.getDrawable(this, android.R.drawable.ic_menu_send), "Copy", "Added to clipboard")
        .setMoreOptionStyle(resources.getDrawable(this, android.R.drawable.ic_menu_search), "Show more")
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.FACEBOOK)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.EMAIL)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.MESSAGE)
        .addPreferredSharingOption(SharingHelper.SHARE_WITH.HANGOUT)
        .setAsFullWidthStyle(true)
        .setSharingTitle("Share With")

    buo.showShareSheet(this, lp, ss, object : Branch.BranchLinkShareListener {
        override fun onShareLinkDialogLaunched() {}
        override fun onShareLinkDialogDismissed() {}
        override fun onLinkShareResponse(sharedLink: String?, sharedChannel: String?, error: BranchError?) {}
        override fun onChannelSelected(channelName: String) {}
    })

Read Deep Link

  • Retrieve Branch data from a deep link

  • Best practice to receive data from the listener (to prevent a race condition)

  • Returns deep link properties

// listener (within Main Activity's onStart)
    Branch.sessionBuilder(this).withCallback(new Branch.BranchReferralInitListener() {
        @Override
        public void onInitFinished(JSONObject referringParams, BranchError error) {
            if (error == null) {
                Log.i(""BRANCH SDK"", referringParams.toString());
            } else {
                Log.i(""BRANCH SDK"", error.getMessage());
            }
        }
    }).withData(this.getIntent().getData()).init();

    // latest
    JSONObject sessionParams = Branch.getInstance().getLatestReferringParams();

    // first
    JSONObject installParams = Branch.getInstance().getFirstReferringParams();
// listener (within Main Activity's onStart)
    Branch.sessionBuilder(this).withCallback(object : BranchReferralInitListener {
        override fun onInitFinished(referringParams: JSONObject?, error: BranchError?) {
            if (error == null) {
                Log.i(""BRANCH SDK"", referringParams.toString())
            } else {
                Log.e(""BRANCH SDK"", error.message)
            }
        }
    }).withData(this.intent.data).init()

    // latest
    val sessionParams = Branch.getInstance().latestReferringParams

    // first
    val installParams = Branch.getInstance().firstReferringParams

Navigate to Content

  • Do stuff with the Branch deep link data
// listener (within Main Activity's onStart)
    Branch.sessionBuilder(this).withCallback(new Branch.BranchReferralInitListener() {
        @Override
        public void onInitFinished(JSONObject referringParams, BranchError error) {
            if (error == null) {

              // option 1: log data
              Log.i(""BRANCH SDK"", referringParams.toString());

              // option 2: save data to be used later
              SharedPreferences preferences = MainActivity.this.getSharedPreferences(""MyPreferences"", Context.MODE_PRIVATE);
              preferences.edit().putString(""branchData"", referringParams.toString()).apply();

              // option 3: navigate to page
              Intent intent = new Intent(MainActivity.this, OtherActivity.class);
              startActivity(intent);

              // option 4: display data
              Toast.makeText(MainActivity.this, referringParams.toString(), Toast.LENGTH_LONG).show();

            } else {
                Log.i(""BRANCH SDK"", error.getMessage());
            }
          }
        }).withData(this.getIntent().getData()).init();
// listener (within Main Activity's onStart)
    Branch.sessionBuilder(this).withCallback(object : BranchReferralInitListener {
        override fun onInitFinished(referringParams: JSONObject?, error: BranchError?) {
            if (error == null) {
                // option 1: log data
                Log.i(""BRANCH SDK"", referringParams.toString())

                // option 2: save data to be used later
                val preferences =  getSharedPreferences(""MyPreferences"", Context.MODE_PRIVATE)
                preferences.edit().putString(""branchData"", referringParams.toString()).apply();

                // option 3: navigate to page
                val intent = Intent(this@MainActivity, MainActivity2::class.java)
                intent.putExtra(""branchData"", referringParams.toString())
                startActivity(intent)

                // option 4: display data
                Toast.makeText(this@MainActivity, referringParams.toString(), Toast.LENGTH_SHORT).show()
            } else {
                Log.e(""BRANCH SDK"", error.message)
            }
        }
    }).withData(this.intent.data).init()

Display Content

implementation 'com.google.firebase:firebase-appindexing:19.0.0' // App indexing
buo.listOnGoogleSearch(this);
buo.listOnGoogleSearch(this);

Track Content

new BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEM).addContentItems(buo).logEvent(context);
BranchEvent(BRANCH_STANDARD_EVENT.VIEW_ITEM).addContentItems(buo).logEvent(context)

Track Users

  • Sets the identity of a user (email, ID, UUID, etc) for events, deep links, and referrals

  • 127 character max for user id

  • Validate with the Branch Dashboard

// login
    Branch.getInstance().setIdentity("your_user_id");

// logout
Branch.getInstance().logout();
// login
    Branch.getInstance().setIdentity("your_user_id");

// logout
Branch.getInstance().logout();

Track Events

  • All events related to a customer purchasing are bucketed into a "Commerce" class of data items

  • All events related to users interacting with your in-app content are bucketed to a "Content" class of data items.

  • All events related to users progressing in your app are bucketed to a "Lifecycle" class of data items.

  • To track custom events - not found in the table below - please see Track Custom Events

  • Validate with the Branch Dashboard

Use the table below to quickly find the event you want to track.

Event Name Event Category Android
Add To Cart Commerce Event BRANCH_STANDARD_EVENT.ADD_TO_CART
Add To Wishlist Commerce Event BRANCH_STANDARD_EVENT.ADD_TO_WISHLIST
View Cart Commerce Event BRANCH_STANDARD_EVENT.VIEW_CART
Initiate Purchase Commerce Event BRANCH_STANDARD_EVENT.INITIATE_PURCHASE
Add Payment Info Commerce Event BRANCH_STANDARD_EVENT.ADD_PAYMENT_INFO
Purchase Commerce Event BRANCH_STANDARD_EVENT.PURCHASE
Spend Credits Commerce Event BRANCH_STANDARD_EVENT.SPEND_CREDITS
Search Content Event BRANCH_STANDARD_EVENT.SEARCH
View Item Content Event BRANCH_STANDARD_EVENT.VIEW_ITEM
View Items Content Event BRANCH_STANDARD_EVENT.VIEW_ITEMS
Rate Content Event BRANCH_STANDARD_EVENT.RATE
Share Content Event BRANCH_STANDARD_EVENT.SHARE
Complete Registration Lifecycle Event BRANCH_STANDARD_EVENT.COMPLETE_REGISTRATION
Complete Tutorial Lifecycle Event BRANCH_STANDARD_EVENT.COMPLETE_TUTORIAL
Achieve Level Lifecycle Event BRANCH_STANDARD_EVENT.ACHIEVE_LEVEL
Unlock Achievement Lifecycle Event BRANCH_STANDARD_EVENT.UNLOCK_ACHIEVEMENT

Handle Push Notifications

  • Deep link to content from GCM push notifications just by adding a Branch link to your result intent
Intent resultIntent = new Intent(this, TargetActivity.class);
resultIntent.putExtra("branch","http://xxxx.app.link/testlink");
resultIntent.putExtra("branch_force_new_session",true);
PendingIntent resultPendingIntent =  PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
val resultIntent = Intent(this, TargetClass::class.java)
resultIntent.putExtra("branch", "http://xxxx.app.link/testlink")
resultIntent.putExtra("branch_force_new_session", true)
val resultPendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT)
  • To handle situations where TargetActivity is in the foreground when push notification is clicked, don't forget to call sessionBuilder()...reInit() from onNewIntent inside TargetActivity:
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
    // if activity is in foreground (or in backstack but partially visible) launching the same
    // activity will skip onStart, handle this case with sessionBuilder()...reInit()
    // will re-initialize only if ""branch_force_new_session=true"" intent extra is set
    Branch.sessionBuilder(this).withCallback(branchReferralInitListener).reInit(this);
}
override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        this.intent = intent
        // Branch reinit (in case Activity is already visible when Branch link is clicked)
        // will re-initialize only if ""branch_force_new_session=true"" intent extra is set
        Branch.sessionBuilder(this).wothCallback(branchListener).reInit()

Handling a new deep link via sessionBuilder()....reInit()

Handling a new deep link via sessionBuilder()....reInit() will clear the current session data, if there is any, and a new referred ""open"" will be attributed.

Handle Links in Your Own App

  • Allows you to deep link into your own app from your app itself by launching a Chrome intent
Intent intent = new Intent(this, ActivityToLaunch.class);
intent.putExtra("branch","http://xxxx.app.link/testlink");
intent.putExtra("branch_force_new_session",true);
startActivity(intent);
val intent = Intent(this, ActivityToLaunch::class.java)
intent.putExtra("branch", "http://xxxx.app.link/testlink")
intent.putExtra("branch_force_new_session", true)
startActivity(intent)

Handling a new deep link

Handling a new deep link in your app will clear the current session data and a new referred "open" will be attributed.

Linking to the currently open activity

Similarly to handling push notifications, linking to the currently open activity or an activity that's in the backstack and partially visible, must be handled via sessionBuilder()....reInit().

Enable 100% Matching

  • Uses Chrome Tabs to increase attribute matching success

  • Add implementation 'com.android.support:customtabs:28.0.0' to your build.gradle

  • If you need the custom tabs library but do not wish to enable 100% matching you can call Branch.enableCookieBasedMatching(null) prior to session initialization.

Delay Session Initialization

Sometimes, users may need to delay session initialization, for example to make an async call to retrieve some data that needs to be passed to Branch as request metadata.

In this case, you may run into an error "SDK already initialized", which happens due to Branch self-initializing the session when Activity enters RESUMED state. To avoid that, you can disable auto-session-initialization manually and initialize the session yourself after the async call finishes.

LauncherActivity.onStart() {
    ...
    Branch.expectDelayedSessionInitialization()
}
asyncOperationCallback() {
    Branch.sessionBuilder(activity).withCallback(callback)...init();
}

Note that the SDK will not be able to perform most operations without session initialization, thus apps must ensure to initialize session on their own (even if, say, asyncOperationCallback is never invoked).

Alternatively, apps can utilize the built-in session delay mechanism like below:

LauncherActivity.onStart() {
    // waits for Branch.getInstance().removeSessionInitializationDelay() or inits after TIMEOUT 
    Branch.sessionBuilder(activity).withCallback(callback).withDelay(TIMEOUT)...init();
}
asyncOperationCallback() {
    // starts session initialization right away
    Branch.getInstance().removeSessionInitializationDelay();
}

Enable / Disable User Tracking

If you need to comply with a user's request to not be tracked for GDPR purposes, or otherwise determine that a user should not be tracked, utilize this field to prevent Branch from sending network requests. This setting can also be enabled across all users for a particular link, or across your Branch links.

Branch.getInstance().disableTracking(true);

You can choose to call this throughout the lifecycle of the app. Once called, network requests will not be sent from the SDKs. Link generation will continue to work, but will not contain identifying information about the user. In addition, deep linking will continue to work, but will not track analytics for the user.

Set initialization metadata

Data Integration Only

If you are using a 3rd Party Data Integration Partner that requires setting certain identifiers before initializing the Branch SDK, you should add this code snippet:

//Before you initialize the session.
Branch.getInstance().setRequestMetadata("{ANALYTICS_ID}", []);

Replace {ANALYTICS_ID} with your Data Integration Partner's key.

Updated 4 days ago

Android Advanced Features


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.