Understanding Android Intents
An Intent is a messaging object used to request an action from another app component (Activity, Service, BroadcastReceiver). Intents are the fundamental mechanism for communication in Android applications, enabling components to interact with each other and with other apps.
Intents serve multiple purposes:
- Component Activation: Start Activities, Services, or BroadcastReceivers
- Inter-App Communication: Enable apps to work together
- Deep Linking: Navigate to specific screens from external sources
- Data Transfer: Pass information between components
Understanding Intents is essential for Android development. They're used in almost every Android app, from simple navigation to complex multi-app workflows.
Explicit Intents: Direct Component Invocation
You specify the exact class to run (e.g., startActivity(context, DetailActivity::class.java)). Used for internal app navigation. Explicit Intents are straightforward—you know exactly which component should handle the action.
When to use Explicit Intents:
- Internal Navigation: Moving between screens within your app
- Component Communication: Starting services or sending broadcasts within your app
- Security: When you don't want other apps to handle the action
- Performance: Slightly faster since Android doesn't need to resolve the target
Example usage:
- Starting a new Activity from a button click
- Launching a Service to perform background work
- Sending a BroadcastReceiver to notify components
Explicit Intents are the safest choice for internal app communication—they can't be intercepted by malicious apps.
Implicit Intents: Action-Based Resolution
You specify the *action* (e.g., ACTION_VIEW, "http://google.com"). The OS finds the best app (Chrome, Firefox) to handle it. Implicit Intents let Android choose the appropriate component based on available apps.
Common Intent Actions include:
- ACTION_VIEW: Display data (open URLs, images, etc.)
- ACTION_SEND: Share content with other apps
- ACTION_DIAL: Open dialer with phone number
- ACTION_PICK: Select item from collection
- ACTION_GET_CONTENT: Get content from another app
Implicit Intents enable:
- App Integration: Work seamlessly with other apps
- User Choice: Users select their preferred app
- System Services: Leverage built-in Android functionality
However, they can be intercepted by malicious apps, so use them carefully for sensitive operations.
Intent Filters: Registering for Implicit Intents
Declared in Manifest. They tell Android "Hey, my app knows how to handle Image Sharing". This registers your app for Implicit Intents. Intent Filters define what actions your app can handle.
An Intent Filter specifies:
- Action: What action the component can handle
- Category: Additional context (CATEGORY_DEFAULT, CATEGORY_BROWSABLE)
- Data: Data type or URI scheme (http://, mailto:, etc.)
Example use cases:
- Deep Linking: Handle custom URL schemes (yourapp://)
- Share Targets: Appear in share menus
- File Handlers: Open specific file types
- URL Handlers: Open HTTP/HTTPS links
Multiple apps can register for the same Intent Filter. Android shows a chooser dialog if multiple apps can handle an Intent. Users can set a default app or choose each time.
Pending Intents: Deferred Execution
A wrapper around an Intent that allows *another* app (like the Notification Manager or Alarm Manager) to execute your Intent later with your permissions. PendingIntents are powerful but can be security risks if misused.
Common use cases:
- Notifications: Tap action launches specific screen
- Widgets: Button clicks perform actions
- Alarms: Scheduled actions execute at specific times
- Shortcuts: App shortcuts execute defined actions
Important considerations:
- Permission Preservation: Executed with your app's permissions
- Security: Can be exploited if accessible to other apps
- Immutability: Cannot be modified after creation
- Flags: FLAG_IMMUTABLE required on newer Android versions
Always use FLAG_IMMUTABLE for PendingIntents unless you specifically need mutability. This prevents security vulnerabilities.
Passing Data with Intents
Use 'Extras' (Bundle). Key-value pairs. Don't pass huge objects (Bitmap) here; it will crash transactions. Pass IDs instead. Intents support several data passing mechanisms:
- Extras (Bundle): Key-value pairs for primitive types and Parcelables
- Data URI: Pass data as part of the Intent's URI
- ClipData: For complex data like file URIs
Best practices for data passing:
- Primitive Types: Strings, ints, booleans—safe to pass directly
- Parcelable Objects: Custom objects implementing Parcelable
- Serializable: Alternative to Parcelable (slower, use sparingly)
- Avoid Large Objects: Bitmaps, large lists—pass URIs or IDs instead
- Size Limits: Android limits Intent data to ~1MB
For large data, use:
- Database IDs (load data from DB in target component)
- File URIs (write to file, pass URI)
- ContentProvider (share data via ContentProvider)
- SharedViewModel (for same-process navigation)
Intent Security: Protecting Against Interception
Implicit Intents can be intercepted. Use App Links (Verified) to ensure your URL opens ONLY your app, preventing phishing intent hijacks. Security considerations for Intents:
- Intent Interception: Malicious apps can register for same filters
- Intent Spoofing: Fake Intents can trick your app
- Data Leakage: Sensitive data in Extras can be accessed
- Permission Escalation: PendingIntents preserve permissions
Security best practices:
- Use Explicit Intents: For internal communication
- App Links (Verified): For handling HTTP/HTTPS URLs
- Verify Intent Source: Check calling package for sensitive operations
- Sanitize Input: Validate all data received via Intents
- Limit Scope: Don't make PendingIntents accessible to other apps
Android App Links use Digital Asset Links to verify app ownership, preventing phishing attacks. Implement them for any app that handles web URLs.
For sensitive operations, always verify the Intent sender using getCallingPackage() or checkIntentFilters. Never trust Intent data without validation—it may have been modified by malicious apps.