Android: отправка письма дефолтным клиентом

gmail-app-with-predefined-text-via-mailto-intent

Задача: отрыть дефолтный email клиент у пользователя на устройстве с предустановленным заголовком письма, текстом и адресатом.

При этом не должно всплывать окно IntentChooser, предоставляющее варианты каким приложением воспользоваться для написания письма. Пользователь должен сразу увидеть его дефолтный email клиент (и это не всегда gmail). Тысячи ответов на StackOverflow показывают диалог, схожий с “share”. Некоторые товарищи в лучшем случае предлагают фильтровать по ContentType и другим косвенным признакам того, что это почтовый клиент, хотя достаточно часто все равно просачиваются приложения вроде Evernote или даже пресловутый bluetooth. Иногда предлагают не переносимые решения, типа использование курсора для получения доступных email клиентов.

Из десятков вариантов решений, которые я перепробовал лучше всего подходит комбинация предложенных методов:

public class ExternalIntents {
    public static final String TAG = ExternalIntents.class.getSimpleName();


    public static void openEmailClient(Activity activity, String email, String subject, String body) {
        Uri emailParams = new Uri.Builder()
            .appendQueryParameter("subject", subject)
            .appendQueryParameter("body", body)
            .build();
        emailParams = Uri.parse("mailto:" + Uri.encode(email) + emailParams.toString());

        Intent intent = new Intent(Intent.ACTION_VIEW)
            .setData(emailParams);

        try {
            activity.startActivity(intent);
        } catch (Exception noEmailClients) {
            Log.w(TAG, "No email clients installed", noEmailClients);

            intent = new Intent(Intent.ACTION_SEND)
                .setType("text/plain")
                .putExtra(Intent.EXTRA_EMAIL, new String[]{email})
                .putExtra(Intent.EXTRA_SUBJECT, subject)
                .putExtra(Intent.EXTRA_TEXT, body);
            try {
                activity.startActivity(Intent.createChooser(intent, "Share via.."));
            } catch (Exception giveUp) {
                Log.e(TAG, "Can't launch any application for this message", giveUp);
            }
        }
    }
}

Использование:

ExternalIntents.openEmailClient(getActivity(),
        getString(R.string.emailPredefinedEmail),
        getString(R.string.emailPredefinedSubject),
        getString(R.string.emailPredefinedBody));