I need to show an E-mail chooser with all installed E-mail apps to the user to select an App and check E-mails (not compose). I'm using the below code.
val intent = Intent(Intent.ACTION_MAIN)
intent.addCategory(Intent.CATEGORY_APP_EMAIL)
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(Intent.createChooser(intent, "Open E-mail"))
But it directly opens the default E-mail app without a chooser. How can I show all supported/installed E-mail apps in the chooser?
I had this problem opening a chooser for only email apps, but I couldn't find a working solution. I wanted the chooser to filter only installed email apps and exclude other applications that can send messages, like social media apps or Bluetooth. Additionally, the solutions I found online only allowed me to send new emails and didn't open the inbox of the email application.
After going through multiple solutions on Stack Overflow, I found a working suggestion that combines different approaches. Here's the solution:
First, add the following code to your AndroidManifest.xml file:
<queries>
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="mailto"/>
</intent>
<intent>
<action android:name="android.intent.action.SEND"/>
<data android:scheme="mailto"/>
</intent>
</queries>
This code allows your app to query and interact with email apps installed on the device.
Next, implement the openMailbox
function:
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.net.Uri
fun Context.openMailbox(chooserTitle: String) {
val mContext: Context = applicationContext
val emailIntent = Intent(Intent.ACTION_VIEW, Uri.parse("mailto:"))
val resInfo = mContext.packageManager.queryIntentActivities(emailIntent, 0)
if (resInfo.isNotEmpty()) {
// First create an intent with only the package name of the first registered email app
// and build a picker based on it
val intentChooser = mContext.packageManager.getLaunchIntentForPackage(
resInfo.first().activityInfo.packageName
)
val openInChooser = Intent.createChooser(intentChooser, chooserTitle)
// Then create a list of LabeledIntent for the rest of the registered email apps
val packageManager = mContext.packageManager
val emailApps = resInfo.toLabeledIntentArray(packageManager)
// Add the rest of the email apps to the picker selection
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailApps)
openInChooser.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(mContext, openInChooser, null)
} else {
// Handle the case where no email apps are installed
}
}
private fun List<ResolveInfo>.toLabeledIntentArray(packageManager: PackageManager): Array<LabeledIntent> =
map {
val packageName = it.activityInfo.packageName
val intent = packageManager.getLaunchIntentForPackage(packageName)
LabeledIntent(intent, packageName, it.loadLabel(packageManager), it.icon)
}.toTypedArray()
You can call the openMailbox
function on a button click or anywhere you want to trigger the intent.
This solution ensures that only installed email apps are displayed in the chooser, allowing users to open their preferred email app and access their inbox directly.
I hope this helps you solve the issue of opening a chooser with filtered email apps in your Android application.