Skip to main content

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
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("message", "Hello World")
startActivity(intent)
getStringExtra() Retrieves a String value from an Intent val message = intent.getStringExtra("message")
putExtras() Used to add a Bundle of key-value pairs
val bundle = Bundle().apply {
    putString("key1", "value1")
    putInt("key2", 42)
}
val intent = Intent(this, SecondActivity::class.java)
intent.putExtras(bundle)
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

  • registerForActivityResult is 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.
val launcher = registerForActivityResult(StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // Handle the result
    }
}
launcher.launch(intent)
ActivityResultContracts.StartIntentSenderForResult Used to start an intent sender and receive a result.
val launcher = registerForActivityResult(StartIntentSenderForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // Handle the result
    }
}
launcher.launch(intentSender)
ActivityResultContracts.RequestPermission Used to request a runtime permission.
val launcher = registerForActivityResult(RequestPermission()) { isGranted ->
    if (isGranted) {
        // Permission granted
    } else {
        // Permission denied
    }
}
launcher.launch(Manifest.permission.CAMERA)
ActivityResultContracts.RequestMultiplePermissions Used to request multiple runtime permissions.
val launcher = registerForActivityResult(RequestMultiplePermissions()) { permissions ->
    val allGranted = permissions.all { it.value }
    if (allGranted) {
        // All permissions granted
    } else {
        // Some permissions denied
    }
}
launcher.launch(arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_CONTACTS))
ActivityResultContracts.GetContent Used to select content from the system (e.g., images, files).
val launcher = registerForActivityResult(GetContent()) { uri ->
    // Handle the selected content URI
}
launcher.launch("image/*")
ActivityResultContracts.GetMultipleContents Used to select multiple content items from the system.
val launcher = registerForActivityResult(GetMultipleContents()) { uris ->
    // Handle the selected content URIs
}
launcher.launch("image/*")
ActivityResultContracts.TakePicturePreview Used to capture a picture and preview it.
val launcher = registerForActivityResult(TakePicturePreview()) { bitmap ->
    // Handle the captured bitmap
}
launcher.launch(null)
ActivityResultContracts.TakePicture Used to capture a picture and save it to a file.
val launcher = registerForActivityResult(TakePicture()) { uri ->
    // Handle the captured image URI
}
launcher.launch(fileUri)
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)
    }
}
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" />
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
val intent = Intent(context, MyReceiver::class.java)
intent.putExtra("data", "example")
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.getActivity() Creates a PendingIntent to launch an Activity
val intent = Intent(context, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
PendingIntent.getService() Creates a PendingIntent to start a Service
val intent = Intent(context, MyService::class.java)
val pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

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.

Was this article helpful?