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)
}
}
<activity
android:name=".ui.MainActivity"
android:exported="true">
<!-- Default launcher intent -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- App Links for verified domains -->
<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="myapp.com"
android:pathPrefix="/posts" />
<data
android:scheme="https"
android:host="myapp.com"
android:path="/search" />
</intent-filter>
<!-- Custom URL scheme -->
<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="myapp"
android:host="post" />
</intent-filter>
</activity>
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.