如何仅使用电子邮件应用程序发送带有附件的电子邮件?

How to send Email with attachment using only email apps?

提问人:ywwynm 提问时间:5/12/2016 最后编辑:Communityywwynm 更新时间:12/20/2016 访问量:1519

问:

有两个要求:

  • 带附件的电子邮件
  • 在选择器中,应该只有电子邮件应用。Intent

我所知道的/所做的:

  • Intent.ACTION_SENDTOwith 可以确保选择器中只有电子邮件应用程序,但它不会带来附件(对于某些应用程序,如 Gmail,它会,但也有许多应用程序会忽略附件)。intent.setData(Uri.parse("mailto:"))Intent

  • Intent.ACTION_SEND可以发送带有附件的电子邮件。但是,在选择器中,将有一些应用程序实际上不是电子邮件应用程序,但可以响应 。使用可以减少这些应用程序的数量,但不是全部。IntentIntent.ACTION_SENDintent.setType("message/rfc822")

  • 参考这个答案:https://stackoverflow.com/a/8550043/3952691 并几乎成功了我的目标。我的代码如下:

    private static void sendFeedbackWithAttachment(Context context, String subject) {
        Intent intent = new Intent(Intent.ACTION_SENDTO);
        intent.setData(Uri.parse("mailto:"));
    
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> resolveInfos = packageManager.queryIntentActivities(intent, 0);
        if (resolveInfos.isEmpty()) {
            Toast.makeText(context, context.getString(R.string.error_activity_not_found),
                    Toast.LENGTH_SHORT).show();
        } else {
            // ACTION_SEND may be replied by some apps that are not email apps. However,
            // ACTION_SENDTO doesn't allow us to choose attachment. As a result, we use
            // an ACTION_SENDTO intent with email data to filter email apps and then send
            // email with attachment by ACTION_SEND.
            List<LabeledIntent> intents = new ArrayList<>();
            Uri uri = getLatestLogUri();
            for (ResolveInfo info : resolveInfos) {
                Intent i = new Intent(Intent.ACTION_SEND);
                i.setPackage(info.activityInfo.packageName);
                i.setClassName(info.activityInfo.packageName, info.activityInfo.name);
                i.putExtra(Intent.EXTRA_EMAIL, new String[] { Def.Meta.FEEDBACK_EMAIL });
                i.putExtra(Intent.EXTRA_SUBJECT, subject);
                i.putExtra(Intent.EXTRA_STREAM, uri);
                intents.add(new LabeledIntent(i, info.activityInfo.packageName,
                        info.loadLabel(context.getPackageManager()), info.icon));
            }
            Intent chooser = Intent.createChooser(intents.remove(0),
                    context.getString(R.string.send_feedback_to_developer));
            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                    intents.toArray(new LabeledIntent[intents.size()]));
            context.startActivity(chooser);
        }
    }
    

    但是,在某些设备上(例如,带有MIUI V2的小米5S,我不知道这是否会受到第三方ROM的影响),结果是一个空的选择器。而且似乎在Android 6.0以上,有一些错误(自定义意图选择器 - 为什么在Android 6上显示空单元格?,另一个:https://code.google.com/p/android/issues/detail?id=202693)。IntentIntent.EXTRA_INITIAL_INTENTS

结果,我不知道如何实现我的目标。请帮帮我,先谢谢你。

Android 电子邮件 android-intent

评论

0赞 CommonsWare 5/17/2016
“Intent.ACTION_SENDTO intent.setData(Uri.parse(”mailto:“)) 可以确保 Intent 选择器中只有电子邮件应用程序” -- 不,它没有。它将选择支持该结构的任何应用放入选择器中。任何人都可以编写这样的应用程序,它可能不是“电子邮件应用程序”。对于什么是“电子邮件应用程序”,没有通用的声明。Intent
0赞 ywwynm 5/17/2016
@CommonsWare 是的,我知道。但我说的是常见情况。我们可以说,一个应用程序具有 for 和数据方案作为“mailto”,如果它是一个正式的应用程序,它应该能够处理电子邮件事件,因此我们可以将其视为“电子邮件应用程序”。IntentFilterIntent.ACTION_SEND
0赞 Stanojkovic 5/19/2016
@ywwynm 使用 .setType(“message/rfc822”),否则选择器将显示支持发送意图的所有(许多)应用程序。
1赞 ywwynm 5/19/2016
@Stanojkovic 你能仔细看看我的问题描述吗?在“我所知道/所做的”部分,我说我尝试使用“message/rfc822”,但它不符合我的需求。
1赞 ywwynm 5/21/2016
@Stanojkovic我确实在“我所知道/做过的事情”部分说过“可以发送带有附件的电子邮件”,对吧?所以我知道如何使用 .我非常非常非常清楚地知道这一点。Intent.ACTION_SENDIntent.ACTION_SEND

答:

-2赞 Hitesh Sahu 5/20/2016 #1

有两种方法可以做到这一点

选项 1

 Intent emailIntent = new Intent(
            android.content.Intent.ACTION_VIEW);

     
     //Option 1
    Uri data = Uri.parse("mailto:?subject=" + "blah blah subject"
            + "&body=" + "blah blah body" + "&to=" + "[email protected]");
    emailIntent.setData(data);

    startActivity(Intent.createChooser(emailIntent, ""));

结果

enter image description here

选项 2

它实际上可以工作,只是它不会过滤掉FTP

    //Option 2
  emailIntent = new Intent(
            android.content.Intent.ACTION_SEND);
    emailIntent.setType("message/rfc822");
    final String[] toRecipients = new String[] { "[email protected]", "", };
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, toRecipients);
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "blah blah subject");
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
            Html.fromHtml("blah blah body"));

    startActivity(Intent.createChooser(emailIntent, ""));

结果

enter image description here

两种方式都有小缺陷,我向你展示两种方式,现在由你来选择一种。

0赞 Jayaprakash G 5/21/2016 #2

尝试以下代码发送邮件

String filename="filename.vcf"; 
File filelocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), filename);
Uri path = Uri.fromFile(filelocation); 
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"[email protected]"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent .putExtra(Intent.EXTRA_STREAM, path);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Subject");
startActivity(Intent.createChooser(emailIntent , "Send email..."));

评论

0赞 IgorGanapolsky 12/20/2016
message/rfc822呢,它设置了电子邮件类型吗?