我需要向用户显示一个电子邮件选择器,其中包含所有已安装的电子邮件应用程序,以选择应用程序并检查电子邮件(而不是撰写)。我正在使用下面的代码。
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"))
但它直接打开默认的电子邮件应用程序,没有选择器。如何在选择器中显示所有支持/安装的电子邮件应用程序?
使用
ACTION_SEND
:
val intent = Intent(Intent.ACTION_SEND).apply {
// The intent does not have a URI, so declare the "text/plain" MIME type
type = "text/plain"
putExtra(Intent.EXTRA_EMAIL, arrayOf("[email protected]")) // recipients
putExtra(Intent.EXTRA_SUBJECT, "Email subject")
putExtra(Intent.EXTRA_TEXT, "Email message text")
}
startActivity(intent)
https://developer.android.com/training/basics/intents/sending
您的原始代码还有:
startActivity(intent)
startActivity(Intent.createChooser(intent, "Open E-mail")
删除重复项
不要忘记考虑零个应用程序符合您的意图的情况:
try {
startActivity(intent)
} catch (e: ActivityNotFoundException) {
// Define what your app should do if no activity can handle the intent.
}
如果系统识别出多个可以处理意图的活动,它会显示一个对话框(有时称为“消歧对话框”)供用户选择要使用的应用程序。如果只有一个活动处理意图,系统会立即启动它。
createChooser
适用于您希望用户每次可能选择不同的应用程序的情况。例如,在分享图像时,也许一次他们想使用 Signal,另一次则想使用 WhatsApp 或 Twitter。
我在仅为电子邮件应用程序打开选择器时遇到此问题,但我找不到有效的解决方案。我希望选择器仅过滤已安装的电子邮件应用程序,并排除其他可以发送消息的应用程序,例如社交媒体应用程序或蓝牙。另外,我在网上找到的解决方案只允许我发送新电子邮件,而无法打开电子邮件应用程序的收件箱。
在研究了 Stack Overflow 上的多种解决方案后,我找到了一个结合了不同方法的可行建议。解决办法如下:
首先,将以下代码添加到您的 AndroidManifest.xml 文件中:
<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>
此代码允许您的应用程序查询设备上安装的电子邮件应用程序并与之交互。
接下来,实现
openMailbox
函数:
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()
您可以在单击按钮或任何您想要触发意图的地方调用
openMailbox
函数。
此解决方案可确保仅已安装的电子邮件应用程序显示在选择器中,从而允许用户打开其首选的电子邮件应用程序并直接访问其收件箱。
我希望这可以帮助您解决在 Android 应用程序中打开带有已过滤电子邮件应用程序的选择器的问题。