Cách mở chương trình Email qua Intents (nhưng chỉ chương trình Email)


76

Tôi muốn thiết lập một phần ứng dụng của mình cho phép người dùng gửi email nhanh cho người dùng khác. Không khó để thiết lập điều này:

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

Tuy nhiên, vấn đề là ACTION_SEND được nhiều chương trình email không chỉ chấp nhận - ví dụ: trên điện thoại của tôi, ứng dụng Facebook, Twitter, reddit rất thú vị và thậm chí Bluetooth cũng trở thành lựa chọn thay thế khả thi để gửi tin nhắn này. Tin nhắn hoàn toàn quá dài đối với một số người trong số này (đặc biệt là Twitter).

Có cách nào để giới hạn trình chọn chỉ với các ứng dụng hỗ trợ tin nhắn dài (chẳng hạn như email)? Hoặc có cách nào để phát hiện ứng dụng mà người dùng đã chọn và điều chỉnh thông báo một cách thích hợp?


2
Tôi đang tự hỏi làm thế nào lớp Linkify quyết định những gì để mở cho các liên kết mailto. Có thể kiểm tra mã nguồn của Linkify và đăng phát hiện của bạn.
Pentium 10

Cuộc gọi tốt - Tôi sẽ kiểm tra và cho bạn biết nếu tôi tìm thấy bất kỳ điều gì quan tâm.
Dan Lew

Cảm ơn một lần nữa Pentium10, gợi ý hay về việc tra cứu cách Linkify hoạt động.
Dan Lew

Câu trả lời:


84

Thay đổi kiểu MIME là câu trả lời, đây là những gì tôi đã làm trong ứng dụng của mình để thay đổi hành vi tương tự. Tôi đã sử dụngintent.setType("message/rfc822");


2
Tôi sẽ không cho rằng mọi chương trình email đều hỗ trợ kiểu MIME đó.
CommonsWare

2
Trong thiết bị của tôi, nó liệt kê Gmail, nhưng cũng có "Drive" và "AndFTP"
Amir Uval

9
Tôi sử dụng Intent mới (Intent.ACTION_SENDTO, Uri.parse ("mailto:"));
Eric Cochran

93

Nhờ gợi ý của Pentium10 về việc tìm kiếm cách hoạt động của Linkify, tôi đã tìm ra giải pháp tuyệt vời cho vấn đề này. Về cơ bản, bạn chỉ cần tạo liên kết "mailto:" và sau đó gọi Ý định thích hợp cho điều đó:

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

Có một số khía cạnh thú vị cho giải pháp này:

  1. Tôi đang sử dụng hành động ACTION_VIEW vì hành động này thích hợp hơn cho liên kết "mailto:". Bạn không thể đưa ra hành động cụ thể nào, nhưng sau đó bạn có thể nhận được một số kết quả không như ý (ví dụ: nó sẽ hỏi bạn xem bạn có muốn thêm liên kết vào danh bạ của mình không).

  2. Vì đây là một liên kết "chia sẻ", tôi chỉ đơn giản là không có địa chỉ email - mặc dù đây là một liên kết mailto. Nó hoạt động.

  3. Không có trình chọn nào tham gia. Lý do cho điều này là để người dùng tận dụng lợi thế của các mặc định; nếu họ đã thiết lập một chương trình email mặc định, thì nó sẽ đưa họ đến thẳng điều đó, hoàn toàn bỏ qua trình chọn (điều này có vẻ tốt trong suy nghĩ của tôi, bạn có thể tranh luận ngược lại).

Tất nhiên có rất nhiều sự khéo léo mà tôi đang bỏ qua (chẳng hạn như mã hóa chủ thể / nội dung đúng cách), nhưng bạn có thể tự mình tìm ra điều đó.


Từ tất cả các giải pháp xung quanh nó đã làm việc cho tôi Cảm ơn bạn thân :)
Bora

2
đây là phương pháp tốt nhất imo bởi vì nó không hiển thị Snapchat Telegram và các ứng dụng khác mà cho phép văn bản gửi
WuerfelDev

5
Trong trường hợp nếu nhu cầu một người nào đó, bạn chỉ định nhận với "& để"
SpiralDev

29

Điều này đã làm việc cho tôi

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

1
Làm việc như một nét duyên dáng .. Đặc biệt Lưu ý rằng Extra_Email phải ở trong chuỗi mảng, Hoặc To: sẽ trống ...
Nilesh

4

Bạn đã thử bao gồm cả phần Intent.EXTRA_EMAILbổ sung?

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

Điều đó có thể hạn chế danh sách các ứng dụng bộ thu khả dụng ...


2
Tôi đã thử điều này, không giúp được gì. Các tính năng bổ sung không được sử dụng để lọc ứng dụng trong trình chọn.
Dan Lew

Tôi nghĩ rằng giải pháp khác duy nhất sẽ là khởi chạy một chương trình thư cụ thể bằng cách truyền một Chuỗi với đường dẫn lớp / gói đầy đủ của nó. Điều này sẽ hạn chế người dùng của bạn ở một ứng dụng Thư, nhưng nó sẽ ngăn các loại ứng dụng khác (như Twitter) trở thành tùy chọn ...
idolize

1
Tôi không thích ý tưởng đó chút nào vì hầu hết người dùng sẽ có hai ứng dụng Thư mặc định để bắt đầu (ứng dụng Thư tiêu chuẩn và Gmail) và tôi không muốn đoán họ sử dụng ứng dụng nào.
Dan Lew

Tôi có 4 ứng dụng email và hầu như không sử dụng ứng dụng Gmail và Mail.
Pentium 10

1

Hãy thử cái này

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

1

Không có giải pháp nào phù hợp với tôi. Cảm ơn nhà phát triển nguồn mở, cketti đã chia sẻ giải pháp ngắn gọn và gọn gàng của anh ấy / cô ấy.

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
}

đây là liên kết đến ý chính của anh ấy / cô ấy.


Đây thực sự là điều duy nhất hoạt động và tôi đã thử 6 giải pháp khác nhau. Cảm ơn bạn.
Mã Wiget

0

Thử thay đổi kiểu MIME từ đơn giản thành tin nhắn

intent.setType("text/message");

0

Đây là một chút lỗi chính tả, vì bạn cần chuyển đổi kiểu mimetype của mình:

intent.setType("plain/text"); //Instead of "text/plain"

1
Theo hiểu biết của tôi, plain/textđây không phải là kiểu MIME hợp lệ. Bạn có một tài liệu tham khảo cho điều này?
Thomas

0

hãy thử tùy chọn này:

Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("message/rfc822");

-1

CHỈ GỬI ĐẾN KHÁCH HÀNG EMAIL - VỚI NHIỀU ĐÍNH KÈM

Có nhiều giải pháp nhưng tất cả đều hoạt động một phần.

mailto lọc đúng các ứng dụng email nhưng nó không có khả năng không gửi các luồng / tệp.

message / rfc822 mở ra địa ngục của ứng dụng cùng với ứng dụng email

vì vậy, giải pháp cho điều này là sử dụng cả hai.

  1. Đầu tiên giải quyết các hoạt động có mục đích bằng cách sử dụng mục đích mailto
  2. Sau đó, đặt dữ liệu cho từng hoạt động được giải quyết để gửi dữ liệu cần thiết
private void share()
{
     Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
     Intent dataIntent  = getDataIntent();

     Intent targetIntent = getSelectiveIntentChooser(context, queryIntent, dataIntent);
     startActivityForResult(targetIntent);
}

Xây dựng ý định dữ liệu bắt buộc chứa đầy dữ liệu cần thiết để chia sẻ

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

Lớp năng lực để lọc các ý định bắt buộc dựa trên ý định truy vấn

// 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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.