Send Email Intent
Stefan Bogdanescu
Founder & Senior Architect
Mastering Intent Choosers: How to Filter External Application Selections on Android
As developers working with Android, understanding how Intents function is fundamental. Intents are the backbone of inter-component communication, allowing different parts of an application, or even external applications, to request actions from each other. When we use methods like startActivity() combined with Intent.createChooser(), we bridge the gap between our app and the operating system's installed applications.
However, sometimes this bridging process presents unexpected user experiences. We often aim to guide the user to the most relevant application, but the default behavior of an Intent chooser is simply to display all registered components that can handle the requested action. This leads us to a common challenge: how do we filter these external choices—for example, showing only email clients when sending an email?
This post will dissect the mechanism behind Intent filtering and explore the subtle, yet powerful, methods used by system developers to restrict application selection, drawing parallels to robust framework design principles found in modern ecosystems like those surrounding Laravel.
The Anatomy of an Email Intent
Let's first look at the provided code snippet, which initiates the email sending process:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html"); // Specifies the MIME type of the data being sent
intent.putExtra(Intent.EXTRA_EMAIL, "emailaddress@emailaddress.com");
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_TEXT, "I'm email body.");
startActivity(Intent.createChooser(intent, "Send Email"));
When Intent.createChooser() is called with an Intent, the Android system queries the device's application manager to find all applications that have registered a handler for that specific action and data type (ACTION_SEND with text/html). The resulting dialog displays whatever apps are capable of handling this general request—hence why you see Bluetooth, Orkut, Skype, and Gmail all listed.
The core issue is that the Android framework itself does not provide a direct API within standard Intents to say, "Only show applications registered as email clients." Filtering the chooser list is therefore an operating system-level decision based on how application manifests are declared, rather than a simple Intent flag.
The Trick Behind Application Filtering
The method you observed in the Android Market trick—where selecting an app with a developer-defined email address filters the subsequent list—is not a direct result of manipulating createChooser() flags but relies on system-level categorization and manifest declarations.
When an application declares specific permissions or uses certain metadata within its Android Manifest, it signals to the system (and potentially other apps) what category it belongs to. For applications that handle standard actions like sending mail, they often register themselves under specific system intents or content providers.
In essence, instead of coding a filter directly into the Intent object, you are leveraging the existing structure defined by the application developer. When an email app is designed correctly, it registers itself in a way that makes it highly discoverable through these system channels. This principle—where structured data dictates behavior across an ecosystem—is vital, whether you are building a complex backend or structuring application manifests; much like how Laravel enforces consistent structure, well-designed Android components must adhere to predictable patterns.
Best Practices for Intent Handling
Since direct filtering isn't available in the standard Intent API, the robust solution involves setting expectations and handling potential outcomes gracefully.
- Rely on System Defaults: For actions like sending mail, it is often best practice to let the system handle the choice unless you have a very specific, tightly controlled environment.
- Post-Selection Validation: If absolute filtering is critical, you must accept the user's selection and validate it immediately after the activity returns. You can check the selected component's package name or intent data to confirm if it is an email client.
For example, after the user selects an application, you would retrieve the result:
// After startActivityForResult() returns the result...
String selectedPackage = getResultIntent.getComponent().getPackageName();
if (selectedPackage.contains("com.google.android.gm") || selectedPackage.contains("com.yahoo.mail")) {
// Proceed with sending, as a valid email app was chosen.
} else {
// Handle the case where an unrelated app was chosen.
Toast.makeText(context, "Please select an email application.", Toast.LENGTH_SHORT).show();
}
Conclusion
Achieving fine-grained control over external application selection via Intents requires understanding the interplay between the application layer and the operating system layer. While you cannot directly tell Intent.createChooser() to exclude apps without knowing their internal registration, by leveraging manifest declarations and post-selection validation, we can create a far more user-friendly and resilient experience. This approach emphasizes predictable structure over relying on opaque system behaviors, reinforcing the principle that well-designed software—whether it’s a web framework or an Android application—must handle edge cases with clarity and robustness.