Have you ever hit the Share button in your app — maybe to send a funny meme, a link, or a photo — and seen that neat list of apps pop up?
As a mobile developer, I always thought it was just… magic. Call an Intent, Android shows a list, job done.
But one day, while debugging a crash on ActivityNotFoundException, I paused and asked myself:
“Wait… how does Android actually know which apps to show? How does it know WhatsApp, Gmail, or Drive can handle my data?”
That question sent me down a rabbit hole that changed how I think about app interactions forever.
Step 1: Understanding the Intent
I started with the basics. An Intent is like a messenger in Android. It carries a message from one part of the system — or even one app — to another.
There are two types of Intents:
-
Explicit Intents: You know exactly which component should handle your request. Example: opening your own
ProfileActivity. - Implicit Intents: You only describe what you want done, not who should do it. Example: sharing an image, sending an email, or opening a PDF. Android figures out the rest.
Step 2: Breaking Down the Implicit Intent
I wrote a tiny snippet in my app:
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_TEXT, "Check out this cool blog!")
type = "text/plain"
}
startActivity(Intent.createChooser(shareIntent, "Share via"))
At first glance, it seems simple. But internally, it’s a beautifully orchestrated dance. Here’s what I realized:
An Implicit Intent has three main parts:
-
Action: What you want to do (
ACTION_SEND= send something). -
Category: The general type of action (
CATEGORY_DEFAULT= standard). -
MIME Type: What type of data you’re sending (
text/plain,image/jpeg, etc.).
These three pieces of info act like a search query to find the right apps.
Step 3: The Journey of an Intent
I wanted to visualize the flow. When I tap Share, this is what happens behind the scenes:
- The Intent hits the Activity Manager Service (AMS): Think of AMS as Android’s traffic controller. It decides: “Where should this message go?”
-
AMS asks the Package Manager Service (PMS) for matches: PMS is a database of all installed apps and their capabilities (declared via
<intent-filter>inAndroidManifest.xml). - PMS matches the Intent to apps: It checks the action, category, and MIME type against every app’s intent filters. All matching apps go into a resolve list.
-
AMS decides what to do next: No matches? Throws
ActivityNotFoundException. One match? Launches it directly. Multiple matches? Shows a chooser dialog (the familiar share sheet).
At this moment, it hit me: the share sheet is not a UI trick. It’s AMS + PMS doing intelligent matching under the hood. Mind blown.
Step 4: A Real Example — Sharing an Image
I tested sharing a photo:
val imageUri: Uri = getImageUri()
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, imageUri)
type = "image/jpeg"
}
startActivity(Intent.createChooser(shareIntent, "Share Image via"))
Here’s what happens:
-
ACTION_SEND→ I want to send something. -
EXTRA_STREAM→ My image URI. -
type = "image/jpeg"→ Only apps that can handle JPEG images appear.
The resolve list might include WhatsApp, Gmail, Drive, etc. Android doesn’t hardcode these — it calculates dynamically based on my device’s installed apps and their intent-filters.
Step 5: How Receiving Apps Register
For apps to show in the share sheet, they declare intent-filters:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
- Action → Can handle
SEND - Category → Default
- Data → Any image
Android matches my Intent against this, adds it to the resolve list, and the app appears as an option. Simple in theory, elegant in execution.
Step 6: Why It Matters for Developers
This little deep dive changed how I design apps:
- Better UX: I can control which apps appear by tweaking MIME types.
- Graceful error handling: I now check for ActivityNotFoundException.
- Powerful cross-app features: I can build apps that communicate seamlessly without hardcoding app dependencies.
It also taught me to think like Android. Every tap, every Intent, every share sheet is a tiny example of Android’s architecture at work.
Step 7: The Takeaway
Next time you tap Share, imagine the journey:
Your Intent → AMS → PMS → Resolve List → Share Sheet → Chosen App
Understanding this makes you not just a developer who “makes things work,” but a developer who understands why things work. And that perspective is invaluable.
Developer Challenge
Open your favorite app and tap Share. Ask yourself:
- How is Android deciding which apps to show?
- What happens if no app can handle my Intent?
- How could I design my app to only show relevant options?
Curiosity leads to mastery. Start small, like I did with ACTION_SEND, and you’ll soon be exploring more complex flows like ACTION_VIEW, ACTION_PICK, and custom deep links.

Top comments (0)