Как открыть программу электронной почты через Intents (но только программу электронной почты) - PullRequest
72 голосов
/ 22 июля 2010

Я хочу настроить часть своего приложения, которая позволит пользователям быстро отправлять электронное письмо другому пользователю. Это не очень сложно настроить:

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);

Однако проблема в том, что ACTION_SEND принимается не только почтовыми программами - например, на моем телефоне приложение Facebook, Twitter, reddit - это весело, и даже Bluetooth представляют собой приемлемую альтернативу для отправки этого сообщения. Сообщение слишком длинное для некоторых из них (особенно для Twitter).

Есть ли способ ограничить выбор только приложениями, которые поддерживают длинные сообщения (например, электронная почта)? Или есть способ определить выбранное пользователем приложение и соответствующим образом настроить сообщение?

Ответы [ 8 ]

88 голосов
/ 22 июля 2010

Благодаря предложению Pentium10 выяснить, как работает Linkify, я нашел отличное решение этой проблемы. По сути, вы просто создаете ссылку «mailto:», а затем вызываете соответствующее намерение для этого .:

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

У этого решения есть несколько интересных аспектов:

  1. Я использую действие ACTION_VIEW, потому что это больше подходит для ссылки "mailto:". Вы не можете предоставить никаких конкретных действий, но тогда вы можете получить некоторые неудовлетворительные результаты (например, он спросит вас, хотите ли вы добавить ссылку на ваши контакты).

  2. Так как это ссылка «поделиться», я просто не указываю адрес электронной почты - даже если это ссылка на почту. Это работает.

  3. Там нет выбора. Причина этого состоит в том, чтобы позволить пользователю воспользоваться преимуществами по умолчанию; если они установили почтовую программу по умолчанию, то они сразу же перейдут к ней, минуя весь выбор (что, на мой взгляд, хорошо, вы можете возразить иначе).

Конечно, я упускаю много тонкостей (например, правильное кодирование предмета / тела), но вы должны сами это выяснить.

81 голосов
/ 02 декабря 2010

Изменение типа MIME - это ответ, это то, что я сделал в своем приложении, чтобы изменить то же поведение.Я использовал intent.setType("message/rfc822");

28 голосов
/ 03 февраля 2013

Это сработало для меня

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 голосов
/ 22 июля 2010

Вы пробовали включить Intent.EXTRA_EMAIL extra?

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..."));

Это может ограничить список доступных приложений для приемника ...

1 голос
/ 28 ноября 2012

Это немного опечатка, так как вам нужно переключить ваш mimetype:

intent.setType("plain/text"); //Instead of "text/plain"
0 голосов
/ 09 февраля 2019

ОТПРАВИТЬ ТОЛЬКО ПОЧТОВЫМ КЛИЕНТАМ - С НЕСКОЛЬКИМИ ПРИЛОЖЕНИЯМИ

Есть много решений, но все работают частично.

mailto правильно фильтрует почтовые приложения, но не может не отправлять потоки / файлы.

message / rfc822 открывает адские приложения вместе с почтовыми клиентами

Итак, решение для этого состоит в том, чтобы использовать оба.

  1. Сначала разрешите действия с намерением, используя mailto intent
  2. Затем установите данные для каждого действия, разрешенного для отправки необходимых данных
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;
}

Класс Utitlity для фильтрации требуемых намерений на основе намерения запроса

// 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;
}
0 голосов
/ 02 июля 2015

попробуйте эту опцию:

Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("message/rfc822");
0 голосов
/ 08 ноября 2010

Попробуйте изменить тип MIME с обычного на сообщение

intent.setType("text/message");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...