Skip to Content

Intents và Navigation

1. Giới thiệu

Intent là cơ chế messaging để yêu cầu hành động từ component khác.

2. Loại Intent

Explicit Intent

Chỉ định rõ component đích:

// Mở Activity cụ thể val intent = Intent(this, DetailActivity::class.java) startActivity(intent)

Implicit Intent

Khai báo action chung, hệ thống chọn component phù hợp:

// Mở URL val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com")) startActivity(intent)

3. Truyền dữ liệu

Primitives

val intent = Intent(this, DetailActivity::class.java).apply { putExtra("id", 123) putExtra("name", "Alice") putExtra("active", true) } startActivity(intent)

Nhận dữ liệu

class DetailActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val id = intent.getIntExtra("id", 0) val name = intent.getStringExtra("name") ?: "" val active = intent.getBooleanExtra("active", false) } }

Parcelable Objects

@Parcelize data class User( val id: Int, val name: String, val email: String ) : Parcelable // Gửi intent.putExtra("user", user) // Nhận val user = intent.getParcelableExtra<User>("user")

4. Implicit Intents phổ biến

Mở trình duyệt

val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com")) startActivity(intent)

Gửi email

val intent = Intent(Intent.ACTION_SENDTO).apply { data = Uri.parse("mailto:") putExtra(Intent.EXTRA_EMAIL, arrayOf("[email protected]")) putExtra(Intent.EXTRA_SUBJECT, "Subject") putExtra(Intent.EXTRA_TEXT, "Email body") } if (intent.resolveActivity(packageManager) != null) { startActivity(intent) }

Gọi điện

val intent = Intent(Intent.ACTION_DIAL).apply { data = Uri.parse("tel:0123456789") } startActivity(intent)

Chia sẻ

val intent = Intent(Intent.ACTION_SEND).apply { type = "text/plain" putExtra(Intent.EXTRA_TEXT, "Check this out!") } startActivity(Intent.createChooser(intent, "Share via"))

Chụp ảnh

val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE) }

5. Activity Result API (Modern)

class MainActivity : ComponentActivity() { private val getContent = registerForActivityResult( ActivityResultContracts.GetContent() ) { uri: Uri? -> // Handle selected image URI } private val takePicture = registerForActivityResult( ActivityResultContracts.TakePicturePreview() ) { bitmap: Bitmap? -> // Handle captured image } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { Column { Button(onClick = { getContent.launch("image/*") }) { Text("Pick Image") } Button(onClick = { takePicture.launch(null) }) { Text("Take Photo") } } } } }

6. Custom Activity Result

// Activity A private val detailLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == Activity.RESULT_OK) { val data = result.data?.getStringExtra("result") // Handle result } } // Launch detailLauncher.launch(Intent(this, DetailActivity::class.java)) // Activity B (DetailActivity) setResult(Activity.RESULT_OK, Intent().apply { putExtra("result", "Success") }) finish()

7. Navigation với Compose

Setup Navigation

@Composable fun NavGraph() { val navController = rememberNavController() NavHost(navController, startDestination = "home") { composable("home") { HomeScreen( onNavigateToDetail = { id -> navController.navigate("detail/$id") } ) } composable( "detail/{id}", arguments = listOf(navArgument("id") { type = NavType.IntType }) ) { backStackEntry -> val id = backStackEntry.arguments?.getInt("id") ?: 0 DetailScreen(id) } } }
// Navigate navController.navigate("detail/123") // Navigate và pop current navController.navigate("home") { popUpTo("home") { inclusive = true } } // Go back navController.popBackStack()

Khai báo trong Manifest

<activity android:name=".MainActivity"> <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="product" /> </intent-filter> </activity>

Trong Compose Navigation

composable( "detail/{id}", deepLinks = listOf(navDeepLink { uriPattern = "myapp://product/{id}" }) ) { backStackEntry -> DetailScreen(backStackEntry.arguments?.getInt("id") ?: 0) }

📝 Tóm tắt

LoạiMục đích
Explicit IntentMở component cụ thể
Implicit IntentYêu cầu action chung
putExtra/getExtraTruyền dữ liệu
ActivityResultAPINhận kết quả từ Activity
NavHostNavigation trong Compose
Deep LinksMở app từ URL
Last updated on