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.