Deep Links in Kotlin: XML Layouts and Intent Filters for Android Apps

Deep links are a powerful way to bring users directly to specific content within your Android app. Instead of just opening the app’s main screen, a deep link navigates users to a particular activity or a specific piece of information. Traditionally, deep links are handled with Intent filters defined in the AndroidManifest.xml file and Kotlin code to parse the incoming URI. This article will provide a detailed walkthrough of how to set up and manage deep links using XML layouts and Intent filters in a Kotlin-based Android app.

Understanding Deep Links

Deep linking allows you to target users from outside of your application—whether it’s from a web page, email, social media, or another app—directly into a specific part of your app. This improves user experience, engagement, and offers enhanced navigational capabilities. When a user clicks a deep link, the system opens your app if it is already installed. If not, users may be directed to the Play Store to install the app, and after installation, the deep link will direct them appropriately.

Benefits of Using Deep Links

  • Improved user experience
  • Enhanced app engagement
  • Seamless navigation to specific content
  • Easier app sharing
  • Better campaign tracking and analytics

Setting up Deep Links with Intent Filters and XML

The primary method for setting up deep links involves declaring Intent filters in your AndroidManifest.xml and then processing the link in your Activity using Kotlin code. This setup tells the Android system that your app can handle specific URLs.
Let’s walk through each step.

Step 1: Update the AndroidManifest.xml

First, you need to declare the activity that will handle the deep link and configure its Intent filters to listen for specific URL schemes, hosts, and paths. The Intent filters must include the android.intent.action.VIEW action, the android.intent.category.DEFAULT category, and the android.intent.category.BROWSABLE category.

<activity
    android:name=".DeepLinkActivity"
    android:exported="true">
    <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"
            android:host="app.example.com"
            android:pathPrefix="/content" />
    </intent-filter>
</activity>

In this example:

  • <activity android:name=".DeepLinkActivity">: Defines the activity DeepLinkActivity which will handle the deep link.
  • android:exported="true": Allows the activity to be invoked by other applications.
  • <action android:name="android.intent.action.VIEW" />: Indicates that the activity displays data to the user.
  • <category android:name="android.intent.category.DEFAULT" />: Ensures the activity is in the list of default activities to perform an action.
  • <category android:name="android.intent.category.BROWSABLE" />: Required for the activity to be accessible via a web browser.
  • <data android:scheme="example" android:host="app.example.com" android:pathPrefix="/content" />: Defines the URL scheme, host, and path prefix the activity can handle.

Step 2: Create the XML Layout for the Activity

Design the XML layout file for DeepLinkActivity to display content related to the deep link.
Here’s a basic example of a layout file, activity_deep_link.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <TextView
        android:id="@+id/textViewDeepLinkData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="16sp"
        android:text="Deep Link Data Here" />

</LinearLayout>

This layout contains a TextView that will display the data extracted from the deep link.

Step 3: Implement the Deep Link Handling in Kotlin

Next, create the Kotlin class DeepLinkActivity. In this class, you will retrieve the data passed via the deep link’s URI.

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity

class DeepLinkActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_deep_link)

        val textViewDeepLinkData: TextView = findViewById(R.id.textViewDeepLinkData)

        val intent: Intent = intent
        val uri: Uri? = intent.data

        if (uri != null) {
            val deepLinkData: String = "Scheme: ${uri.scheme}n" +
                    "Host: ${uri.host}n" +
                    "Path: ${uri.path}n" +
                    "Query: ${uri.query}"

            textViewDeepLinkData.text = deepLinkData
        } else {
            textViewDeepLinkData.text = "No Deep Link Data Found"
        }
    }
}

Explanation:

  • setContentView(R.layout.activity_deep_link): Sets the layout for the activity.
  • val textViewDeepLinkData: TextView = findViewById(R.id.textViewDeepLinkData): Initializes the TextView from the layout.
  • val intent: Intent = intent: Retrieves the Intent that started this activity.
  • val uri: Uri? = intent.data: Extracts the URI from the Intent.
  • uri?.let { ... }: Executes the code block if the URI is not null.
  • The code retrieves and displays the scheme, host, path, and query parameters of the URI.
  • If there is no URI data, it sets the TextView to indicate that no deep link data was found.

Step 4: Testing the Deep Link

You can test the deep link using the adb command via the terminal:

adb shell am start -W -a android.intent.action.VIEW -d "example://app.example.com/content?item=123" your.package.name

Replace your.package.name with the actual package name of your application.

This command launches your app with the specified URL. The DeepLinkActivity should open, displaying the deep link data.

Advanced Deep Linking Techniques

To handle more complex scenarios, you can incorporate several advanced techniques:

Handling Multiple Schemes and Hosts

You can add multiple <data> tags to handle different schemes and hosts.

<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" android:host="app.example.com" />
    <data android:scheme="https" android:host="www.example.com" />
</intent-filter>

This enables the same activity to handle links from example://app.example.com and https://www.example.com.

Parsing Parameters

You can extract parameters from the URI query and use them to customize the user experience. For example, you may want to display a product with a specific ID.

val itemId: String? = uri?.getQueryParameter("item")
if (!itemId.isNullOrEmpty()) {
    textViewDeepLinkData.text = "Item ID: $itemId"
}

This retrieves the value of the item parameter from the URL and displays it in the TextView.

Using App Links

App Links provide a secure way to associate your app with your website. To set up App Links, you need to configure the assetlinks.json file on your website and verify the links with Google.

Here’s an example of how to declare App Links in the AndroidManifest.xml:

<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="www.example.com" />
</intent-filter>

The android:autoVerify="true" attribute tells the system to verify that the app is associated with the website specified in the <data> tag. Follow the official Android documentation to configure the assetlinks.json file correctly.

Best Practices for Deep Linking

  • Handle Errors Gracefully: Provide feedback to the user if the deep link is invalid or leads to non-existent content.
  • Use Specific and Clear URLs: Use descriptive and straightforward URLs to facilitate easy user understanding.
  • Test Thoroughly: Test deep links across various devices and scenarios to ensure they work as expected.
  • Monitor Performance: Use analytics to track the performance of your deep links and identify areas for improvement.
  • Document Deep Link Structures: Properly document all the deep link structures your app supports, aiding future maintenance and scaling efforts.

Conclusion

Deep links are an essential tool for driving engagement and improving user experience in Android apps. By combining Intent filters in XML with Kotlin code to handle incoming URIs, developers can seamlessly direct users to specific content within the app. This guide covers basic setup, advanced techniques, and best practices, giving you a comprehensive understanding of how to implement deep links effectively. Make sure to thoroughly test and optimize your deep link implementations for the best possible user experience. With the techniques described, your app can provide a seamless navigation experience, whether from web pages, social media, or other applications.