So öffnen Sie ein E-Mail-Programm über Absichten (aber nur ein E-Mail-Programm)

76

Ich möchte einen Teil meiner Anwendung einrichten, mit dem Benutzer eine schnelle E-Mail an einen anderen Benutzer senden können. Es ist nicht sehr schwer, dies einzurichten:

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

Das Problem ist jedoch, dass ACTION_SEND nicht nur von E-Mail-Programmen akzeptiert wird. Auf meinem Telefon macht beispielsweise die Facebook-App Twitter, reddit Spaß, und sogar Bluetooth ist eine praktikable Alternative zum Senden dieser Nachricht. Die Nachricht ist für einige von ihnen (insbesondere Twitter) viel zu lang.

Gibt es eine Möglichkeit, die Auswahl auf Anwendungen zu beschränken, die lange Nachrichten unterstützen (z. B. E-Mail)? Oder gibt es eine Möglichkeit, die vom Benutzer ausgewählte App zu erkennen und die Nachricht entsprechend anzupassen?

Dan Lew
quelle
2
Ich frage mich, wie die Linkify-Klasse entscheidet, was für Mailto-Links geöffnet werden soll. Überprüfen Sie möglicherweise den Quellcode von Linkify und veröffentlichen Sie Ihre Ergebnisse.
Pentium10
Guter Anruf - ich werde das überprüfen und Sie wissen lassen, wenn ich etwas Interessantes finde.
Dan Lew
Nochmals vielen Dank, Pentium10, ein guter Vorschlag, wie Linkify die Dinge macht.
Dan Lew

Antworten:

84

Das Ändern des MIME-Typs ist die Antwort. Dies habe ich in meiner App getan, um das gleiche Verhalten zu ändern. ich benutzteintent.setType("message/rfc822");

Jeff S.
quelle
2
Ich würde nicht davon ausgehen, dass jedes E-Mail-Programm diesen MIME-Typ unterstützt.
CommonsWare
2
Auf meinem Gerät werden Google Mail, aber auch "Drive" und "AndFTP" aufgelistet
Amir Uval
9
Ich verwende new Intent (Intent.ACTION_SENDTO, Uri.parse ("mailto:"));
Eric Cochran
92

Dank des Vorschlags von Pentium10, nach der Funktionsweise von Linkify zu suchen, habe ich eine großartige Lösung für dieses Problem gefunden. Grundsätzlich erstellen Sie einfach einen "mailto:" - Link und rufen dann die entsprechende Absicht dafür auf:

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

Diese Lösung hat einige interessante Aspekte:

  1. Ich verwende die Aktion ACTION_VIEW, da dies für einen "mailto:" - Link besser geeignet ist. Sie können keine bestimmte Aktion angeben, erhalten dann jedoch möglicherweise unbefriedigende Ergebnisse (z. B. werden Sie gefragt, ob Sie den Link zu Ihren Kontakten hinzufügen möchten).

  2. Da dies ein "Teilen" -Link ist, füge ich einfach keine E-Mail-Adresse hinzu - obwohl dies ein Mailto-Link ist. Es klappt.

  3. Es ist kein Wähler beteiligt. Der Grund dafür ist, dass der Benutzer die Standardeinstellungen nutzen kann. Wenn sie ein Standard-E-Mail-Programm festgelegt haben, gelangen sie direkt dazu und umgehen die Auswahl insgesamt (was meiner Meinung nach gut erscheint, können Sie anders argumentieren).

Natürlich lasse ich eine Menge Finesse aus (z. B. die richtige Kodierung des Motivs / Körpers), aber Sie sollten in der Lage sein, dies selbst herauszufinden.

Dan Lew
quelle
Von all der Lösung hat es bei mir funktioniert Danke Kumpel :)
Bora
2
Dies ist die beste Methode imo, weil es nicht Snapchat, Telegramm und andere Apps zeigt, die das Senden von Text ermöglichen
WuerfelDev
5
In Fällen, in denen jemand benötigt, geben Sie den Empfänger mit "& to" an
SpiralDev
29

Das hat bei mir funktioniert

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[] {"[email protected]"});
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..."));
Haris ur Rehman
quelle
1
Arbeitete wie ein Zauber. Beachten Sie insbesondere, dass sich Extra_Email im String-Array befinden sollte, oder dass To: leer sein wird ...
Nilesh
4

Haben Sie versucht, das Intent.EXTRA_EMAILExtra aufzunehmen?

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

Dies kann die Liste der verfügbaren Empfängeranwendungen einschränken ...

vergöttern
quelle
2
Ich habe es versucht, hilft nicht. Extras werden nicht zum Filtern der Apps in einer Auswahl verwendet.
Dan Lew
Ich denke, die einzige andere Lösung wäre, ein bestimmtes Mail-Programm zu starten, indem ein String mit dem vollständigen Klassen- / Paketpfad übergeben wird. Dies würde Ihre Benutzer auf eine Mail-App beschränken, aber es würde verhindern, dass andere Arten von Apps (wie Twitter) Optionen sind ...
Idolize
1
Diese Idee gefällt mir überhaupt nicht, da die meisten Benutzer zunächst zwei Standard-Mail-Apps haben (die Standard-Mail-App und Google Mail), und ich möchte nicht erraten, welche sie verwenden.
Dan Lew
Ich habe 4 E-Mail-Clients und benutze kaum die Google Mail- und Mail-App.
Pentium10
1

Probier diese

Intent intent = new Intent("android.intent.action.SENDTO", Uri.fromParts("mailto", "[email protected]", null));
intent.putExtra("android.intent.extra.SUBJECT", "Enter Subject Here");
startActivity(Intent.createChooser(intent, "Select an email client")); 
Ashish
quelle
1

Keine der Lösungen hat bei mir funktioniert. Dank des Open Source-Entwicklers cketti für das Teilen seiner prägnanten und übersichtlichen Lösung.

String mailto = "mailto:[email protected]" +
    "?cc=" + "[email protected]" +
    "&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
}

Und dies ist die Verbindung zu seinem Kern.

user10496632
quelle
Dies ist buchstäblich das einzige, was funktioniert und ich habe 6 verschiedene Lösungen ausprobiert. Vielen Dank.
Code Wiget
0

Versuchen Sie, den MIME-Typ von normal in Nachricht zu ändern

intent.setType("text/message");
BadSkillz
quelle
0

Dies ist ein Tippfehler, da Sie Ihren Mimetyp wechseln müssen:

intent.setType("plain/text"); //Instead of "text/plain"
Peterdk
quelle
1
Nach meinem besten Wissen plain/textist kein gültiger MIME-Typ. Haben Sie eine Referenz dafür?
Thomas
0

Versuchen Sie diese Option:

Intent intentEmail = new Intent(Intent.ACTION_SEND);
intentEmail.setType("message/rfc822");
Ashish Jaiswal
quelle
-1

NUR AN E-MAIL-KUNDEN SENDEN - MIT MEHREREN BEFESTIGUNGEN

Es gibt viele Lösungen, aber alle funktionieren teilweise.

mailto filtert E-Mail-Apps ordnungsgemäß, kann jedoch keine Streams / Dateien senden.

message / rfc822 öffnet eine Menge Apps zusammen mit E-Mail-Clients

Die Lösung hierfür besteht darin, beide zu verwenden.

  1. Lösen Sie zuerst Absichtsaktivitäten mit mailto intent
  2. Stellen Sie dann die Daten auf jede aufgelöste Aktivität ein, um die erforderlichen Daten zu senden
private void share()
{
     Intent queryIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:"));
     Intent dataIntent  = getDataIntent();

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

Erstellen Sie die erforderliche Datenabsicht, die mit den erforderlichen Daten zum Teilen gefüllt ist

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-Klasse zum Filtern erforderlicher Absichten basierend auf der Abfrageabsicht

// 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;
}
Ayyappa
quelle