Deep linking and App Links

Alex Chen Jan 2026
2 tabs
package com.example.myapp.ui

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment
import com.example.myapp.R
import com.example.myapp.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        handleDeepLink(intent)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { handleDeepLink(it) }
    }

    private fun handleDeepLink(intent: Intent) {
        val action = intent.action
        val data: Uri? = intent.data

        when {
            action == Intent.ACTION_VIEW && data != null -> {
                // Handle deep link
                val postId = data.lastPathSegment?.toIntOrNull()
                val query = data.getQueryParameter("q")

                when (data.host) {
                    "myapp.com" -> handleWebDeepLink(data, postId, query)
                    "app" -> handleCustomSchemeDeepLink(data, postId)
                }
            }
            intent.hasExtra("post_id") -> {
                // Handle notification click
                val postId = intent.getIntExtra("post_id", -1)
                if (postId != -1) {
                    navigateToPost(postId)
                }
            }
        }
    }

    private fun handleWebDeepLink(uri: Uri, postId: Int?, query: String?) {
        when {
            uri.path?.startsWith("/posts/") == true && postId != null -> {
                navigateToPost(postId)
            }
            uri.path == "/search" && query != null -> {
                navigateToSearch(query)
            }
            uri.path == "/profile" -> {
                navigateToProfile()
            }
            else -> {
                // Unknown deep link - show home
            }
        }
    }

    private fun handleCustomSchemeDeepLink(uri: Uri, postId: Int?) {
        // Handle custom scheme: myapp://post/{id}
        if (uri.host == "post" && postId != null) {
            navigateToPost(postId)
        }
    }

    private fun navigateToPost(postId: Int) {
        val navHostFragment = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val navController = navHostFragment.navController

        val bundle = Bundle().apply {
            putInt("postId", postId)
        }
        navController.navigate(R.id.postDetailFragment, bundle)
    }

    private fun navigateToSearch(query: String) {
        val navHostFragment = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val navController = navHostFragment.navController

        val bundle = Bundle().apply {
            putString("query", query)
        }
        navController.navigate(R.id.searchFragment, bundle)
    }

    private fun navigateToProfile() {
        val navHostFragment = supportFragmentManager
            .findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        val navController = navHostFragment.navController

        navController.navigate(R.id.profileFragment)
    }
}
2 files · kotlin, xml Explain with highlit

Deep links open specific app content from external sources. I configure intent filters in AndroidManifest with URL schemes—http, https, or custom. App Links verify ownership via assetlinks.json on your domain, providing seamless no-dialog opening. Intent.getData() extracts URI in Activity. Navigation component handles deep links declaratively in nav graph. Deferred deep links preserve attribution through install. Testing uses adb shell am commands. Dynamic Links create short URLs surviving install. Branch and Firebase provide advanced deep linking with analytics. Deep links improve user experience by directing users to relevant content, support marketing campaigns, and enable cross-platform flows between web and mobile.