Working with Intents and Navigation
1. Creating Explicit Intents
| Property | Description | Example |
|---|---|---|
| Intent() | Constructor for creating an explicit intent | val intent = Intent(this, SecondActivity::class.java) |
| Intent(context, activityClass) | Creates an intent to launch a specific activity | val intent = Intent(this, ProfileActivity::class.java) |
| putExtra() | Adds data to the intent as key-value pairs | intent.putExtra("userId", 123) |
Example: Launching an Activity with Intent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button = findViewById<Button>(R.id.button)
button.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
}
}
Example: Passing Data with Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("title", "Android Development")
intent.putExtra("id", 456)
startActivity(intent)
2. Creating Implicit Intents
| Property | Description | Example |
|---|---|---|
| action | Defines the action to be performed, e.g., ACTION_VIEW, ACTION_SEND | "android.intent.action.VIEW" |
| data | URI of the data to be handled, e.g., a web URL or file path | Uri.parse("https://example.com") |
| type | MIME type of the data, used for filtering | "text/plain" |
| category | Additional category of the intent, e.g., CATEGORY_DEFAULT | "android.intent.category.DEFAULT" |
Example: Opening a Web Page
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.com"))
startActivity(intent)
Example: Sharing Text
val intent = Intent().apply {
action = Intent.ACTION_SEND
type = "text/plain"
putExtra(Intent.EXTRA_TEXT, "Hello, World!")
}
startActivity(Intent.createChooser(intent, "Share via"))
3. Starting Activities
| Method | Description | Usage |
|---|---|---|
| startActivity(Intent) | Starts a new activity using an Intent | startActivity(Intent(activityClass)) |
| startActivityForResult(Intent, Int) | Starts an activity and expects a result back | startActivityForResult(Intent(activityClass), requestCode) |
| startActivity(Intent, Bundle?) | Starts an activity with options | startActivity(Intent(activityClass), bundle) |
Example: Starting an Activity
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
Example: Starting an Activity with Data
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user_id", 123)
startActivity(intent)
Note: When starting an activity, ensure the target activity is declared in
AndroidManifest.xml.
4. Passing Data with Intents
| Method | Description | Example |
|---|---|---|
| putExtra() | Used to add key-value pairs to an Intent | |
| getStringExtra() | Retrieves a String value from an Intent | val message = intent.getStringExtra("message") |
| putExtras() | Used to add a Bundle of key-value pairs | |
Note: All primitive types and serializable objects can be passed via
putExtra().Warning: Large data objects should not be passed via Intents due to size limitations.
| Type | Method | Notes |
|---|---|---|
| String | putExtra("key", "value") |
Basic string data |
| Int | putExtra("key", 123) |
Integer value |
| Boolean | putExtra("key", true) |
Boolean value |
| Serializable | putExtra("key", object) |
Custom objects must implement Serializable |
| Parcelable | putExtra("key", object) |
More efficient than Serializable, preferred for performance |
5. Using Intent Filters
| Filter Type | Description | Usage |
|---|---|---|
| ACTION_MAIN | Indicates the activity is the main entry point of the app. | Intent intent = new Intent(Intent.ACTION_MAIN); |
| ACTION_VIEW | Used to view a resource specified by a URI. | Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com")); |
| ACTION_SEND | Used to send data to another app. | Intent intent = new Intent(Intent.ACTION_SEND); |
| CATEGORY_DEFAULT | Indicates that the activity can be launched as a default category. | intent.addCategory(Intent.CATEGORY_DEFAULT); |
Example: Handling Intent Filters in Android Manifest
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Example: Filtering for Web Content
<activity
android:name=".WebActivity"
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="http" android:host="example.com" />
</intent-filter>
</activity>
Note: Intent filters are matched based on the action, category, and data of an intent. Make sure to define all necessary components for your filter.
6. Handling Intent Results
| Method | Description | Notes |
|---|---|---|
| startActivityForResult() | Launches an activity and expects a result back | Deprecated in API level 30, use registerForActivityResult instead |
| registerForActivityResult() | Registers a callback to receive the result from an activity | Newer and recommended approach for handling results |
Example: Using registerForActivityResult
class MainActivity : AppCompatActivity() {
private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
// Handle the result
}
}
private fun launchActivity() {
val intent = Intent(this, SecondActivity::class.java)
launcher.launch(intent)
}
}
Note: The
registerForActivityResult API is preferred over startActivityForResult as it provides better lifecycle management and cleaner code structure.
Key Points
registerForActivityResultis the modern way to handle intent results- It avoids issues with lifecycle and memory leaks
- Use
ActivityResultContracts.StartActivityForResult()for standard activity launches
7. Using Activity Result Contracts
Activity Result Contracts simplify the process of starting activities and handling their results in Android. They provide a type-safe way to launch activities and receive results without the need for boilerplate code.
| Contract | Description | Usage Example |
|---|---|---|
| ActivityResultContracts.StartActivityForResult | Used to start an activity and receive a result. | |
| ActivityResultContracts.StartIntentSenderForResult | Used to start an intent sender and receive a result. | |
| ActivityResultContracts.RequestPermission | Used to request a runtime permission. | |
| ActivityResultContracts.RequestMultiplePermissions | Used to request multiple runtime permissions. | |
| ActivityResultContracts.GetContent | Used to select content from the system (e.g., images, files). | |
| ActivityResultContracts.GetMultipleContents | Used to select multiple content items from the system. | |
| ActivityResultContracts.TakePicturePreview | Used to capture a picture and preview it. | |
| ActivityResultContracts.TakePicture | Used to capture a picture and save it to a file. | |
Note: Activity Result Contracts are part of the AndroidX library and require
androidx.activity:activity-ktx dependency.Example: Using Activity Result Contracts to Request Permissions
class MainActivity : AppCompatActivity() {
private val permissionLauncher = registerForActivityResult(
RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
// Permission granted, proceed with camera usage
openCamera()
} else {
// Permission denied, show rationale or disable feature
Toast.makeText(this, "Camera permission required", Toast.LENGTH_SHORT).show()
}
}
private fun requestCameraPermission() {
permissionLauncher.launch(Manifest.permission.CAMERA)
}
private fun openCamera() {
// Launch camera intent
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivity(intent)
}
}
8. Implementing Deep Links
| Property | Description | Example |
|---|---|---|
| android:autoVerify | Enables automatic verification of deep links | <intent-filter android:autoVerify="true"> |
| android:scheme | URI scheme (e.g., http, https) | <data android:scheme="https" /> |
| android:host | Domain name for the deep link | <data android:host="example.com" /> |
| android:path | Path component of the URI | <data android:path="/product/123" /> |
Example: Deep Link Intent
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com/product/123"))
startActivity(intent)
Note: Ensure your app's
AndroidManifest.xml includes the appropriate intent filters to handle deep links.
Warning: Deep links must be verified to prevent security vulnerabilities.
9. Using PendingIntents
| Property | Description | Example |
|---|---|---|
| PendingIntent.getBroadcast() | Creates a PendingIntent to broadcast an Intent | |
| PendingIntent.getActivity() | Creates a PendingIntent to launch an Activity | |
| PendingIntent.getService() | Creates a PendingIntent to start a Service | |
Example: Using PendingIntent in Notification
val intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, "channel_id")
.setContentTitle("Example Notification")
.setContentText("Tap to open app")
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(pendingIntent)
.build()
Note:
PendingIntent.FLAG_UPDATE_CURRENT ensures that if a PendingIntent already exists, it will be updated with new data.Warning: Avoid using
PendingIntent.FLAG_MUTABLE in Android 12+ as it can cause security issues. Prefer PendingIntent.FLAG_IMMUTABLE.10. Sharing Data with ShareSheet
| Property | Description | Example |
|---|---|---|
| Intent.ACTION_SEND | Used to share data with other apps | val intent = Intent(Intent.ACTION_SEND) |
| Intent.EXTRA_TEXT | Text to be shared | intent.putExtra(Intent.EXTRA_TEXT, "Hello World") |
| Intent.EXTRA_STREAM | URI of a file to be shared | intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://...")) |
| Intent.TYPE | MIME type of the content being shared | intent.type = "text/plain" |
Example: Sharing Text
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Check out this cool app!")
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
Example: Sharing an Image
val imageUri = Uri.parse("file:///path/to/image.jpg")
val sendIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, imageUri)
type = "image/jpeg"
}
val shareIntent = Intent.createChooser(sendIntent, null)
startActivity(shareIntent)
Note: Ensure that the file URI is accessible to other apps, or use
FileProvider for secure sharing.
Warning: When sharing files, make sure to set the correct MIME type to avoid compatibility issues.