Deep Links

Typically you’ll want to open Rover experiences through deep links and universal links (sometimes referred to as App Links). This is useful for integrating with a push notification automation solution or a CMS, and in the case of universal links, external communications such as email.

Deep links are for URIs that bear a custom schema specific to your app, e.g.:

example://experience?id=…

Android's documentation explains more about how to handle Links within your app: Create Deep Links to App Content.


Many of the resources in the Rover SDK can be navigated to via “deep link”. A Rover deep link is comprised of a scheme, a path and optional parameters.

As is standard on Android, you will need an Activity to handle the incoming links. The following serves as a simple boilerplate example of how to handle the links, but if you have your own routing infrastructure, you may certainly make use of it.

You will need to setup a specific URI structure to be used for presenting Rover experiences in your app. The simplest approach is to use a specific URI path/host and include the experience ID and (optional) campaign ID as query parameters. The manifest included with this sample app and below example code demonstrates how to route URIs given in the following format to a Rover experience:

In this example example is the scheme, experience is the host and campaignID=xxx and id=xxx are parameters.

Intent Filter

Add an intent filter for your deep links to the manifest entry for your Activity, with the deep link scheme you acquired above (here assumed to be example):

<activity android:name="…"><!-- for deep links -->
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="example" />
    </intent-filter>
</activity>

Handling deep links formatted with a query paramater:

example://experience?id=<EXPERIENCE_ID>&campaignID=<CAMPAIGN_ID>
override fun onCreate(savedInstanceState: Bundle?) {
    /* ... other onCreate() logic ... */

    val uri : Uri = intent.data ?: return

    // Tries to retrieve experienceId query parameter:
    val queryExperienceId = uri.getQueryParameter("id")

    if (uri.scheme == getString(R.string.uri_scheme) && uri.host == "experience" && queryExperienceId != null) {
        startActivity(
            RoverActivity.makeIntent(
                packageContext = this,
                experienceId = queryExperienceId
            )
        )
        return
    }
}

Campaign Attribution

Often you will want to present an experience as the result of a specific marketing campaign. The RoverActivity can be associated with an arbitrary campaign ID when it is activated. When a campaign ID is passed to the initializer, the RoverViewController will include it in all events it broadcasts. See the events section for details on how to capture Rover events in your analytics tracking.

To attribute an experience launching from a deep link with a campaign ID, include an additional campaignID parameter in the deep link.

myapp://experience?id=<EXPERIENCE_ID>&campaignID=<CAMPAIGN_ID>

Update your URI handling code to parse the optional campaignID and pass it to the RoverViewController initializer.

override fun onCreate(savedInstanceState: Bundle?) {
    /* ... other onCreate() logic ... */

    val uri : Uri = intent.data ?: return

    // Tries to retrieve experienceId query parameter:
    val queryExperienceId = uri.getQueryParameter("id")

    // Tries to retrieve campaignId query parameter if one was given:
    val queryCampaignId = uri.getQueryParameter("campaignID")
    if (uri.scheme == getString(R.string.uri_scheme) && uri.host == "experience" && queryExperienceId != null) {
        startActivity(
            RoverActivity.makeIntent(
                packageContext = this,
                experienceId = queryExperienceId,
                campaignId = queryCampaignId
                )
            )
        return
    }
}

Alternative URI Structures

If the standard approach above does not meet your needs you can setup any arbitrary URI to launch a Rover experience as long as you can extract the experience ID from it. For example you could use a path based approach which includes the experience ID and optional campaign ID as path components instead of query string parameters. The below example demonstrates how to route URLs in that format to a Rover experience. Note that the intent filter does not need to change in this case.

example://experience/<EXPERIENCE_ID>/<CAMPAIGN_ID>
override fun onCreate(savedInstanceState: Bundle?) {
    /* ... other onCreate() logic ... */

    val uri : Uri = intent.data ?: return

    if(uri.scheme == getString(R.string.uri_scheme) && uri.host == "experience" && uri.pathSegments[0] != null) {
        val pathExperienceId: String = uri.pathSegments[0]
        val pathCampaignId: String? = uri.pathSegments.getOrNull(1)
        startActivity(RoverActivity.makeIntent(packageContext = this, experienceId = pathExperienceId, campaignId = pathCampaignId))
    }
}