Deep Links in Android Using Jetpack

This tutorial will walk you through using Jetpack to set up deep links to enable users of your Android application move from one part of your application to another or to other applications.

· 5 min read
Wilson Ochieng

Wilson Ochieng

Android Expert developing mobile applications with 4+ Years of Experience.

topics

Introduction

Android Deep Links give you a way to link straight to particular features or content inside your application. By enabling users to go straight from an external source such as a web page, email, or another application to a specific area of the app, they improve the user experience. URI deep links and App links are the two main categories into which deep links can be classified. URI deep links allow users to go within the application’s custom schemes such as myapp://profile/123, whereas App Links use HTTP URLs that are authenticated as belonging to your domain improves security and user confidence.An example of HTTP URL is https://time.com/6999323/elon-musk-move-x-spacex-headquarters-texas-california/.

Because of its declarative UI architecture, Jetpack Compose makes adding deep links in the context of contemporary Android development a simplified process. Deep links are only one of the many tools that Jetpack Compose offers to manage navigation while streamlining UI development. Developers can create a unified and responsive user experience by utilizing Jetpack Navigation Compose to easily incorporate deep links into their composable screens.

Deep linkages are very beneficial to the usability and engagement of apps. They make it easier for users to access particular areas of an app, which increases the effectiveness of navigation overall. This can be especially helpful in situations where customers need to quickly access certain content, including user profiles, promotional offers, or in-depth product pages. Deep links give developers a means to improve the operation of their applications and guarantee that users can easily get the content they require.

This tutorial will walk you through using Jetpack Compose to set up deep links in an Android application. We will launch a brand-new Android project, set up deep links, and walk through how to manage navigation upon clicking a deep link. By the time you finish this article, you will know exactly how to add deep links to your Jetpack Compose application to improve accessibility and usability.

Prerequisites

- Prerequisites,Basic knowledge of Kotlin, Jetpack Compose, and Android development.

Step 1: Set Up a New Android Project

  1. Open Android Studio and create a new project.
  2. Select "Empty Compose Activity" as the template and proceed.

Image

3.Name your project DeepLinkComposeApp, choose a suitable package name, and finish the setup.

Image

Step 2: Add the required dependencies.


dependencies {

    implementation(libs.androidx.core.ktx)
    implementation(libs.androidx.lifecycle.runtime.ktx)
    implementation(libs.androidx.activity.compose)
    implementation(platform(libs.androidx.compose.bom))
    implementation(libs.androidx.ui)
    implementation(libs.androidx.ui.graphics)
    implementation(libs.androidx.ui.tooling.preview)
    implementation(libs.androidx.material3)
    implementation (libs.androidx.navigation.compose)
    testImplementation(libs.junit)
    androidTestImplementation(libs.androidx.junit)
    androidTestImplementation(libs.androidx.espresso.core)
    androidTestImplementation(platform(libs.androidx.compose.bom))
    androidTestImplementation(libs.androidx.ui.test.junit4)
    debugImplementation(libs.androidx.ui.tooling)
    debugImplementation(libs.androidx.ui.test.manifest)
}

Step 3: Define Navigation and Deep Links

-In your MainActivity.kt, set up navigation and handle deep links.

-Create a NavController and NavHost.The arguments from the NavBackStackEntry should be extracted and made available in the lambda of the composable() function.

-You must append the parameter to the route when making the navigate call in order to pass it to the destination.

package com.example.deeplinkcomposeapp

import android.content.Intent
import android.graphics.fonts.FontStyle
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.rounded.ShoppingCart
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
import com.example.deeplinkcomposeapp.ui.theme.DeepLinkComposeAppTheme
import org.w3c.dom.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            DeepLinkComposeAppTheme {
                val navController = rememberNavController()

                NavHost(navController, startDestination = "home") {
                    composable("home") {
                        HomeScreen { navController.navigate("article/elon-musk-move-x-spacex") }
                    }
                    composable(
                        "article/{articleId}",
                        arguments = listOf(navArgument("articleId") { type = NavType.StringType }),
                        deepLinks = listOf(navDeepLink { uriPattern = "https://time.com/6999323/{articleId}" })
                    ) { backStackEntry ->
                        val articleId = backStackEntry.arguments?.getString("articleId")
                        ArticleScreen(articleId)
                    }
                }
            }
        }

        // Handle the intent that triggered the deep link
        handleDeepLink(intent)
    }

    private fun handleDeepLink(intent: Intent?) {
        intent?.data?.let { uri ->
            if (uri.scheme == "https" && uri.host == "time.com") {
                val articleId = uri.lastPathSegment
                // Navigate to the article screen with the articleId
                (this as? ComponentActivity)?.setContent {
                    val navController = rememberNavController()
                    navController.navigate("article/$articleId")
                }
            }
        }
    }
}

@Composable
fun HomeScreen(onArticleClick: () -> Unit) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        contentAlignment = Alignment.Center
    ) {
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { onArticleClick() },
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
            colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.primaryContainer)
        ) {
            Column(
                modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth(),
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Icon(
                    imageVector = Icons.Filled.Email,
                    contentDescription = "Newspaper Icon",
                    modifier = Modifier.size(40.dp)
                )
                Spacer(modifier = Modifier.height(8.dp))

                Text(
                    text = "Tech News",
                    fontSize = 30.sp,
                    )


            }
        }
    }
}

@Composable
fun ArticleScreen(articleId: String?) {
    Box(
        modifier = Modifier.fillMaxSize(),
        contentAlignment = Alignment.Center
    ) {
        Text(text = "Article Screen for Article ID: $articleId")
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    DeepLinkComposeAppTheme {
        HomeScreen {}
    }
}

Step 4: Configure the AndroidManifest.xml

Add the intent filter to handle deep links in your AndroidManifest.xml.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.DeepLinkComposeApp"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.DeepLinkComposeApp">

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

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

</manifest>

Step 5:Navigate to a composable with arguments

When you click the Tech News Button,you will be redirected to users composable.

Home Screen

Image

Article Screen

Image

Step 6: Test the Deep Link

To test the deep link, run the app on an emulator or device. Use the adb tool to send an intent to the app:

Image

The link will open in the browser as demonstrated below.

Image


Conclusion

By enabling direct navigation to particular information, Jetpack Compose's deep link integration improves the user experience within an Android application. This lesson showed how to configure the required parts, handle deep link intents, and build up deep links in a Compose-based application. You may give your users a smooth and simple navigating experience by following these steps.

Deep links are an effective way to increase accessibility and app engagement. Developers can achieve more user-friendliness and dynamic apps by effectively managing and implementing deep links by utilizing Jetpack Compose's declarative approach to UI and navigation. Deep links can improve user interactions and simplify navigation, so keep that in mind as you develop and improve your application.




share

Wilson Ochieng

Android Expert developing mobile applications with 4+ Years of Experience.