代码之家  ›  专栏  ›  技术社区  ›  Dan Lew

如何通过意图打开电子邮件程序(但仅限于电子邮件程序)

  •  72
  • Dan Lew  · 技术社区  · 14 年前

    我想设置我的应用程序的一部分,允许用户发送一个快速的电子邮件给另一个用户。设置这个并不难:

    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("text/plain");
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_TEXT, message);
    Intent mailer = Intent.createChooser(intent, null);
    startActivity(mailer);
    

    然而,问题是,发送的动作不仅仅被电子邮件程序所接受——例如,在我的手机上,Facebook应用程序、Twitter、reddit很有趣,甚至蓝牙都是发送这条消息的可行替代方案。对于其中一些人(尤其是Twitter)来说,消息太长了。

    有没有办法将选择器限制为只支持长消息(如电子邮件)的应用程序?或者有没有办法检测用户选择的应用程序并适当调整消息?

    9 回复  |  直到 14 年前
        1
  •  86
  •   gprathour davidbuzatto    10 年前

    改变MIME类型就是答案,这就是我在我的应用程序中所做的改变同样的行为。我曾经 intent.setType("message/rfc822");

        2
  •  94
  •   Dan Lew    14 年前

    感谢Pentium10关于搜索Linkify如何工作的建议,我找到了解决这个问题的好方法。基本上,您只需创建一个“mailto:”链接,然后调用相应的Intent:

    Intent intent = new Intent(Intent.ACTION_VIEW);
    Uri data = Uri.parse("mailto:?subject=" + subject + "&body=" + body);
    intent.setData(data);
    startActivity(intent);
    

    这个解决方案有几个有趣的方面:

    1. 因为这是一个“共享”链接,我只是不包括电子邮件地址-即使这是一个mailto链接。它起作用了。

    2. 没有选择者。这样做的原因是让用户利用默认值;如果他们已经设置了一个默认的电子邮件程序,那么他们就会直接这样做,完全绕过选择器(在我看来这很好,你可能会反对)。

    当然,我遗漏了很多技巧(比如对主题/主体进行适当编码),但你应该能够自己解决这个问题。

        3
  •  29
  •   Haris ur Rehman    12 年前

    Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
    emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    emailIntent.setType("vnd.android.cursor.item/email");
    emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] {"abc@xyz.com"});
    emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Email Subject");
    emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "My email content");
    startActivity(Intent.createChooser(emailIntent, "Send mail using..."));
    
        4
  •  4
  •   idolize    14 年前

    你试过把 Intent.EXTRA_EMAIL

    Intent mailer = new Intent(Intent.ACTION_SEND);
    mailer.setType("text/plain");
    mailer.putExtra(Intent.EXTRA_EMAIL, new String[]{"name@email.com"});
    mailer.putExtra(Intent.EXTRA_SUBJECT, subject);
    mailer.putExtra(Intent.EXTRA_TEXT, bodyText);
    startActivity(Intent.createChooser(mailer, "Send email..."));
    

    可能会限制可用接收器应用程序的列表。。。

        5
  •  1
  •   Ashish    5 年前

    试试这个

    Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "yourmail@gmail.com", null));
    intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
    startActivity(Intent.createChooser(intent, "Select an email client")); 
    
        6
  •  1
  •   user10496632    5 年前

    所有的解决方案都不适合我。多亏了开源开发者, 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

        7
  •  0
  •   BadSkillz    14 年前

    尝试将MIME类型从普通更改为消息

    intent.setType("text/message");
    
        8
  •  0
  •   Peterdk    12 年前

    这有点输入错误,因为您需要切换mimetype:

    intent.setType("plain/text"); //Instead of "text/plain"
    
        9
  •  0
  •   Sujay DÅ©ng Nguyễn    9 年前

    尝试此选项:

    Intent intentEmail = new Intent(Intent.ACTION_SEND);
    intentEmail.setType("message/rfc822");
    
        10
  •  -1
  •   Ayyappa    6 年前

    仅发送到电子邮件客户端-带有多个附件

    有很多解决方案,但都能部分解决问题。

    电子邮件 正确过滤电子邮件应用程序,但它无法不发送流/文件。

    信息/rfc822 打开地狱般的应用程序和电子邮件客户端

    1. 然后将数据设置到每个已解析的活动,以发送所需的数据
    private void share()
    {
         Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
         Intent dataIntent  = getDataIntent();
    
         Intent targetIntent = getSelectiveIntentChooser(context, queryIntent, dataIntent);
         startActivityForResult(targetIntent);
    }
    

    private Intent getDataIntent()
    {
            Intent dataIntent = buildIntent(Intent.ACTION_SEND, null, "message/rfc822", null);
    
            // Set subject
            dataIntent.putExtra(Intent.EXTRA_SUBJECT, title);
    
            //Set receipient list.
            dataIntent.putExtra(Intent.EXTRA_EMAIL, toRecipients);
            dataIntent.putExtra(Intent.EXTRA_CC, ccRecipients);
            dataIntent.putExtra(Intent.EXTRA_BCC, bccRecipients);
            if (hasAttachments())
            {
                ArrayList<Uri> uris = getAttachmentUriList();
    
                if (uris.size() > 1)
                {
                    intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                    dataIntent.putExtra(Intent.EXTRA_STREAM, uris);
                }
                else
                {
                    dataIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris.get(0));
                }
            }
    
            return dataIntent;
    }
    
    protected ArrayList<Uri> getAttachmentUriList()
    {
            ArrayList<Uri> uris = new ArrayList();
            for (AttachmentInfo eachAttachment : attachments)
            {
                uris.add(eachAttachment.uri);
            }
    
            return uris;
    }
    

    用于根据查询意图筛选所需意图的实用性类

    // Placed in IntentUtil.java
    public static Intent getSelectiveIntentChooser(Context context, Intent queryIntent, Intent dataIntent)
    {
            List<ResolveInfo> appList = context.getPackageManager().queryIntentActivities(queryIntent, PackageManager.MATCH_DEFAULT_ONLY);
    
            Intent finalIntent = null;
    
            if (!appList.isEmpty())
            {
                List<android.content.Intent> targetedIntents = new ArrayList<android.content.Intent>();
    
                for (ResolveInfo resolveInfo : appList)
                {
                    String packageName = resolveInfo.activityInfo != null ? resolveInfo.activityInfo.packageName : null;
    
                    Intent allowedIntent = new Intent(dataIntent);
                    allowedIntent.setComponent(new ComponentName(packageName, resolveInfo.activityInfo.name));
                    allowedIntent.setPackage(packageName);
    
                    targetedIntents.add(allowedIntent);
                }
    
                if (!targetedIntents.isEmpty())
                {
                    //Share Intent
                    Intent startIntent = targetedIntents.remove(0);
    
                    Intent chooserIntent = android.content.Intent.createChooser(startIntent, "");
                    chooserIntent.putExtra(android.content.Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
                    chooserIntent.addFlags(android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION);
    
                    finalIntent = chooserIntent;
                }
    
            }
    
            if (finalIntent == null) //As a fallback, we are using the sent data intent
            {
                finalIntent = dataIntent;
            }
    
            return finalIntent;
    }