我的应用程序集成了电子邮件功能,用户可以直接从应用中提交错误报告、反馈等。 我使用 application/octet-stream 作为 Intent 的 SetType。 当您尝试提交电子邮件时,会弹出内容选择器并显示来自 Evernote、Facebook、电子邮件等的各种选项。
我该如何让这个选择器仅显示电子邮件,以避免让用户看到与内容选择器类型不符的其他选项,从而混淆用户?
谢谢。
我的应用程序集成了电子邮件功能,用户可以直接从应用中提交错误报告、反馈等。 我使用 application/octet-stream 作为 Intent 的 SetType。 当您尝试提交电子邮件时,会弹出内容选择器并显示来自 Evernote、Facebook、电子邮件等的各种选项。
我该如何让这个选择器仅显示电子邮件,以避免让用户看到与内容选择器类型不符的其他选项,从而混淆用户?
谢谢。
要解决此问题,只需遵循官方文档即可。最重要的考虑因素是:
标志为ACTION_SENDTO
,而不是ACTION_SEND
。
意图的setData方法,
intent.setData(Uri.parse("mailto:")); // 仅电子邮件应用程序应处理此项
如果发送空的Extra
,则结尾处的if()
将无法工作,应用程序将无法启动电子邮件客户端。
这对我有用。根据Android文档,如果您想确保您的意图仅由电子邮件应用程序(而不是其他短信或社交应用程序)处理,则使用ACTION_SENDTO操作并包括"mailto:"数据方案。例如:
public void composeEmail(String[] addresses, String subject) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
https://developer.android.com/guide/components/intents-common.html#Email
https://developer.android.com/guide/components/intents-common.html#Email我假设您正在使用 ACTION_SEND
Intent
操作,因为您没有详细说明您正在使用什么,但您同意了 @Aleadam 的评论。
我将 application/octet-stream 用作 Intent 的 SetType。
该句中没有限制事物只能用于电子邮件。
ACTION_SEND
是一个通用的 Intent
操作,可以由任何希望支持它的应用程序支持。你所要做的就是指示你要共享的数据和该数据的 MIME 类型-接下来,用户就可以从可用的活动中进行选择。
当 @Jasoon 指出时,你可以尝试使用 message/rfc822
作为 MIME 类型。然而,这并不表示"只提供电子邮件客户端"-它表示"提供任何支持 message/rfc822 数据"。这很可能包括一些不是电子邮件客户端的应用程序。
如果你特别想通过电子邮件发送某些东西,那么请将 JavaMail 集成到你的应用程序中,或者在你的 Web 服务器上编写一个电子邮件转发脚本并调用它。如果你使用 ACTION_SEND
,那么你默认认为用户想要什么很重要,你希望用户能够通过用户选择的任何方式发送这样和这样的数据。
在实现“魔法链接”功能时,我遇到了一个问题,即为所有已安装的电子邮件应用程序创建选择器意图:
private void openEmailApp() {
List<Intent> emailAppLauncherIntents = new ArrayList<>();
//Intent that only email apps can handle:
Intent emailAppIntent = new Intent(Intent.ACTION_SENDTO);
emailAppIntent.setData(Uri.parse("mailto:"));
emailAppIntent.putExtra(Intent.EXTRA_EMAIL, "");
emailAppIntent.putExtra(Intent.EXTRA_SUBJECT, "");
PackageManager packageManager = getPackageManager();
//All installed apps that can handle email intent:
List<ResolveInfo> emailApps = packageManager.queryIntentActivities(emailAppIntent, PackageManager.MATCH_ALL);
for (ResolveInfo resolveInfo : emailApps) {
String packageName = resolveInfo.activityInfo.packageName;
Intent launchIntent = packageManager.getLaunchIntentForPackage(packageName);
emailAppLauncherIntents.add(launchIntent);
}
//Create chooser
Intent chooserIntent = Intent.createChooser(new Intent(), "Select email app:");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toArray(new Parcelable[emailAppLauncherIntents.size()]));
startActivity(chooserIntent);
}
PackageManager.MATCH_ALL
可能会误导。我认为这将禁用操作系统自动执行的任何结果过滤(可能是通过用户设置)。这可能不是您想要的。标准的 PackageManager.MATCH_DEFAULT_ONLY
在某些情况下可能更合适。 - Acadian_GhostKotlin答案
如果您需要仅显示电子邮件应用程序,然后您想要仅打开收件箱(不是打开新的电子邮件撰写),则需要执行A和B:
A)由于{{link1:Android 11的软件包可见性更新}},请在Android 11中的AndroidManifest.xml文件中添加以下代码:
<queries>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
<intent>
<action android:name="android.intent.action.CHOOSER" />
</intent>
</queries>
B) 使用以下函数显示电子邮件选择器:
// Show email app list.
fun showEmailAppList() {
// Email app list.
val emailAppLauncherIntents: MutableList<Intent?> = ArrayList()
// Create intent which can handle only by email apps.
val emailAppIntent = Intent(Intent.ACTION_SENDTO)
emailAppIntent.data = Uri.parse("mailto:")
// Find from all installed apps that can handle email intent and check version.
val emailApps = packageManager.queryIntentActivities(
emailAppIntent,
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) 0 else PackageManager.MATCH_ALL
)
// Collect email apps and put in intent list.
for (resolveInfo in emailApps) {
val packageName = resolveInfo.activityInfo.packageName
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
emailAppLauncherIntents.add(launchIntent)
}
// Create chooser with created intent list to show email apps of device.
val chooserIntent = Intent.createChooser(Intent(), "OPEN EMAIL APP")
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, emailAppLauncherIntents.toTypedArray())
startActivity(chooserIntent)
}
结果:
可以将意图选择器的选项限制为仅几个选项。 此问题的答案 中的代码是一个很好的例子。实质上,您需要创建一个 LabeledIntents 列表,提供给意图选择器,然后将其包含在列表中。请注意,此解决方案不是通过排除(某些应用程序被排除,而其余应用程序保留),而是您必须选择要显示哪些应用程序。希望能有所帮助!
它适用于所有设备。它只会显示电子邮件应用程序。
public static void shareViaMail(Activity activity, String title, String body, String filePath) {
Uri URI = Uri.parse("file://" + filePath);
final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"contact@brightsociety.com"});
if (URI != null) {
emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
}
try {
activity.startActivity(emailIntent);
} catch (Exception e) {
((BaseActivity) activity).showToast("Gmail App is not installed");
e.printStackTrace();
}
}
经过大量的搜索和测试,我终于找到了一个完美的解决方案。感谢开源开发者cketti分享他/她简洁而整洁的解决方案。
String mailto = "mailto:bob@example.org" +
"?cc=" + "alice@example.com" +
"&subject=" + Uri.encode(subject) +
"&body=" + Uri.encode(bodyText);
Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse(mailto));
try {
startActivity(emailIntent);
} catch (ActivityNotFoundException e) {
//TODO: Handle case where no email app is available
}
这是他/她的代码片段链接:this。
解决方案非常简单:
Intent testIntent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.parse("mailto:?subject=" + "blah blah subject" + "&body=" + "blah blah body" + "&to=" + "sendme@me.com");
testIntent.setData(data);
startActivity(testIntent);
它可以在所有设备上运行。它只会显示电子邮件应用程序。
public static void shareViaMail(Activity activity, String title, String body, String filePath) {
Uri URI = Uri.parse("file://" + filePath);
final Intent emailIntent = new Intent(Intent.ACTION_VIEW);
emailIntent.setData(Uri.parse("mailto:"));
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"xyz@gmail.com"});
/*if you want to attach something*/
if (URI != null) {
emailIntent.putExtra(Intent.EXTRA_STREAM, URI);
}
try {
activity.startActivity(emailIntent);
} catch (Exception e) {
((BaseActivity) activity).showToast("Gmail App is not installed");
e.printStackTrace();
}
}