Come inviare e-mail dalla mia applicazione Android?


Risposte:


978

Il modo migliore (e più semplice) è usare un Intent:

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"recipient@example.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject of email");
i.putExtra(Intent.EXTRA_TEXT   , "body of email");
try {
    startActivity(Intent.createChooser(i, "Send mail..."));
} catch (android.content.ActivityNotFoundException ex) {
    Toast.makeText(MyActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
}

Altrimenti dovrai scrivere il tuo client.


6
Nel codice sopra, non esiste un ID e-mail del mittente, quindi come viene inviato il messaggio?
KIRAN KJ,

38
KIRAN: Devi capire come funzionano gli Intenti per capirlo. Fondamentalmente aprirà un'applicazione di posta elettronica con il destinatario, l'oggetto e il corpo già compilati. Spetta all'app di posta elettronica eseguire l'invio.
Jeremy Logan,

8
L'email non viene visualizzata nel campo "TO" avviando l'attività. qualcuno lo sa?
Hamza Waqas,

11
il grande contributo di questo commento è: messaggio / rfc822
Guilherme Oliveira

22
aggiungere questi per essere sicuri che il selettore visualizzi solo le app di posta elettronica: Intent i = new Intent(Intent.ACTION_SENDTO); i.setType("message/rfc822"); i.setData(Uri.parse("mailto:"));
Edris,

194

Usa .setType("message/rfc822")o il selettore ti mostrerà tutte le (molte) applicazioni che supportano l'intento di invio.


5
Bene, questo dovrebbe avere più voti in su. Non noterai i test sull'emulatore, ma quando vai a inviare "text / plain" su un dispositivo reale ti darà un elenco di oltre 15 app !! quindi "message / rfc822" è decisamente raccomandato (lo standard e-mail).
Blundell,

7
@Blundell ciao, ma non ho visto alcuna differenza dopo essere passato amessage/rfc822
disegna il

2
Puoi rimuovere il bluetooth dall'elenco? Questo si presenta anche con questo tipo. +1 però, trucco accurato!
ingh.am,

4
Abbiamo salvato la nostra pancetta. Non riesco a immaginare di spiegare al cliente che l'utente potrebbe twittare le richieste di supporto invece di inviarle via e-mail.
Kevin Galligan,

1
+1111111 Questo merita +1 infiniti, così gli altri possono vederlo. Ho perso questa parte e ho dovuto affrontare questo problema per un po '!
Sfida

89

Lo sto usando da molto tempo e sembra buono, nessuna app non e-mail visualizzata. Solo un altro modo per inviare un intento di invio email:

Intent intent = new Intent(Intent.ACTION_SENDTO); // it's not ACTION_SEND
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject of email");
intent.putExtra(Intent.EXTRA_TEXT, "Body of email");
intent.setData(Uri.parse("mailto:default@recipient.com")); // or just "mailto:" for blank
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // this will make such that when user returns to your app, your app is displayed, instead of the email app.
startActivity(intent);

1
Azione non opportuna: questa azione non è attualmente supportata
erdomester

4
lgor G-> cambia plz da setType "(plain / text") a setType ("text / plain")
cach

2
.setType ("message / rfc822") non text / plain
The Hungry Androider

1
questo codice aprirà intento email? come posso inviare e-mail senza mostrare l'intenzione all'utente @yuku voglio inviare la password a e
Erum

2
Questa risposta è abbastanza influente . :)
Nick Volynkin,

54

Stavo usando qualcosa sulla falsariga della risposta attualmente accettata per inviare e-mail con un file di registro degli errori binario allegato. GMail e K-9 lo inviano bene e arriva anche bene sul mio server di posta. L'unico problema era il mio client di posta di scelta Thunderbird che aveva problemi con l'apertura / il salvataggio del file di registro allegato. In effetti, semplicemente non ha salvato il file senza lamentarsi.

Ho dato un'occhiata a uno di questi codici sorgente di posta e ho notato che l'allegato del file di registro aveva (comprensibilmente) il tipo mime message/rfc822. Ovviamente quell'allegato non è un'e-mail allegata. Ma Thunderbird non può far fronte con grazia a quel piccolo errore. Quindi era una specie di seccatura.

Dopo un po 'di ricerca e sperimentazione ho trovato la seguente soluzione:

public Intent createEmailOnlyChooserIntent(Intent source,
    CharSequence chooserTitle) {
    Stack<Intent> intents = new Stack<Intent>();
    Intent i = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto",
            "info@domain.com", null));
    List<ResolveInfo> activities = getPackageManager()
            .queryIntentActivities(i, 0);

    for(ResolveInfo ri : activities) {
        Intent target = new Intent(source);
        target.setPackage(ri.activityInfo.packageName);
        intents.add(target);
    }

    if(!intents.isEmpty()) {
        Intent chooserIntent = Intent.createChooser(intents.remove(0),
                chooserTitle);
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,
                intents.toArray(new Parcelable[intents.size()]));

        return chooserIntent;
    } else {
        return Intent.createChooser(source, chooserTitle);
    }
}

Può essere usato come segue:

Intent i = new Intent(Intent.ACTION_SEND);
i.setType("*/*");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(crashLogFile));
i.putExtra(Intent.EXTRA_EMAIL, new String[] {
    ANDROID_SUPPORT_EMAIL
});
i.putExtra(Intent.EXTRA_SUBJECT, "Crash report");
i.putExtra(Intent.EXTRA_TEXT, "Some crash report details");

startActivity(createEmailOnlyChooserIntent(i, "Send via email"));

Come puoi vedere, il metodo createEmailOnlyChooserIntent può essere facilmente alimentato con l'intento corretto e il tipo mime corretto.

Quindi passa attraverso l'elenco delle attività disponibili che rispondono a un mailtointento di protocollo ACTION_SENDTO (che sono solo app di posta elettronica) e crea un selettore in base a tale elenco di attività e all'intento ACTION_SEND originale con il tipo MIME corretto.

Un altro vantaggio è che Skype non è più elencato (che risponde al tipo mime rfc822).


1
ti ho appena inserito lo snippet di codice e funziona benissimo. Prima c'erano app elencate come Google Drive, Skype ecc. Ma non c'è un modo per inviare un'e-mail dall'applicazione senza chiamare un'altra applicazione? ho appena letto l'articolo sul client di posta elettronica che @Rene postet sopra, ma sembra essere troppo complicato per l'invio di una semplice e
Alex Cio

Risposta eccellente. Ho avuto anche Skype e Google Drive ACTION_SENDe questo lo risolve magnificamente.
darrenp,

1
La soluzione più popolare sopra restituisce anche Skype e Vkontakte. Questa soluzione è migliore.
Denis Kutlubaev, il

che cos'è crashLogFile? dove è stato inizializzato? pease sepecify
Noufal

@Noufal Questo è solo qualche residuo della mia base di codice. È Fileun'istanza che punta a un file di registro degli arresti anomali creato dalle mie app Android in background in caso di eccezione non rilevata. Quell'esempio dovrebbe semplicemente illustrare come aggiungere un allegato e-mail. È inoltre possibile allegare qualsiasi altro file dalla memoria esterna (ad esempio un'immagine). Puoi anche rimuovere quella linea con crashLogFileper ottenere un esempio funzionante.
Tiguchi,

37

Per LASCIARE SOLO APP EMAIL per risolvere il tuo intento, devi specificare ACTION_SENDTO come Azione e mailto come Dati.

private void sendEmail(){

    Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
    emailIntent.setData(Uri.parse("mailto:" + "recipient@example.com")); 
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "My email's subject");
    emailIntent.putExtra(Intent.EXTRA_TEXT, "My email's body");

    try {
        startActivity(Intent.createChooser(emailIntent, "Send email using..."));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(Activity.this, "No email clients installed.", Toast.LENGTH_SHORT).show();
    }

}

23

Ho risolto questo problema con semplici righe di codice, come spiega la documentazione di Android.

( https://developer.android.com/guide/components/intents-common.html#Email )

La più importante è la bandiera: lo è ACTION_SENDTOe nonACTION_SEND

L'altra linea importante è

intent.setData(Uri.parse("mailto:")); ***// only email apps should handle this***

A proposito, se si invia uno spazio vuoto Extra, if()alla fine non funzionerà e l'app non avvierà il client di posta elettronica.

Secondo la documentazione Android. Se vuoi assicurarti che il tuo intento sia gestito solo da un'app di posta elettronica (e non da altre app di messaggistica o social), usa l' ACTION_SENDTOazione e includi lo " mailto:" schema di dati. Per esempio:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

21

La strategia di utilizzo .setType("message/rfc822")o ACTION_SENDsembra corrispondere anche alle app che non sono client di posta elettronica, come Android Beam e Bluetooth .

L'uso ACTION_SENDTOe un mailto:URI sembrano funzionare perfettamente ed è raccomandato nella documentazione per gli sviluppatori . Tuttavia, se lo fai sugli emulatori ufficiali e non ci sono account di posta elettronica impostati (o non ci sono client di posta), viene visualizzato il seguente errore:

Azione non supportata

Tale azione non è attualmente supportata.

Come mostrato di seguito:

Azione non supportata: quell'azione non è attualmente supportata.

Si scopre che gli emulatori risolvono l'intenzione in un'attività chiamata com.android.fallback.Fallback, che visualizza il messaggio sopra. Apparentemente questo è di progettazione.

Se vuoi che la tua app aggiri questo in modo che funzioni correttamente anche sugli emulatori ufficiali, puoi verificarlo prima di provare a inviare l'e-mail:

private void sendEmail() {
    Intent intent = new Intent(Intent.ACTION_SENDTO)
        .setData(new Uri.Builder().scheme("mailto").build())
        .putExtra(Intent.EXTRA_EMAIL, new String[]{ "John Smith <johnsmith@yourdomain.com>" })
        .putExtra(Intent.EXTRA_SUBJECT, "Email subject")
        .putExtra(Intent.EXTRA_TEXT, "Email body")
    ;

    ComponentName emailApp = intent.resolveActivity(getPackageManager());
    ComponentName unsupportedAction = ComponentName.unflattenFromString("com.android.fallback/.Fallback");
    if (emailApp != null && !emailApp.equals(unsupportedAction))
        try {
            // Needed to customise the chooser dialog title since it might default to "Share with"
            // Note that the chooser will still be skipped if only one app is matched
            Intent chooser = Intent.createChooser(intent, "Send email with");
            startActivity(chooser);
            return;
        }
        catch (ActivityNotFoundException ignored) {
        }

    Toast
        .makeText(this, "Couldn't find an email app and account", Toast.LENGTH_LONG)
        .show();
}

Trova maggiori informazioni nella documentazione per gli sviluppatori .


13

L'invio di e-mail può essere effettuato con Intents che non richiede alcuna configurazione. Ma poi richiederà l'interazione dell'utente e il layout sarà un po 'limitato.

Costruire e inviare un'e-mail più complessa senza l'interazione dell'utente comporta la creazione del proprio client. La prima cosa è che l'API Sun Java per e-mail non è disponibile. Ho avuto successo sfruttando la libreria Apache Mime4j per creare e-mail. Tutto basato sui documenti di nilvec .


6

Ecco il codice di lavoro di esempio che apre l'applicazione di posta nel dispositivo Android e si riempie automaticamente di indirizzo e oggetto nella posta di composizione.

protected void sendEmail() {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:feedback@gmail.com"));
    intent.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Grazie. Confrontando con una soluzione di @Avi Parshan, si imposta un'e-mail setData()e Avi si attiva putExtra(). Entrambe le varianti funzionano. Ma se si rimuove setDatae si utilizza solo intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"});, ci sarebbe un ActivityNotFoundException.
CoolMind

5

Uso il codice seguente nelle mie app. Questo mostra esattamente le app client di posta elettronica, come Gmail.

    Intent contactIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", getString(R.string.email_to), null));
    contactIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.email_subject));
    startActivity(Intent.createChooser(contactIntent, getString(R.string.email_chooser)));

5

Questo ti mostrerà solo i client di posta elettronica (oltre a PayPal per qualche motivo sconosciuto)

 public void composeEmail() {

    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:"));
    intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"hi@example.com"});
    intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
    intent.putExtra(Intent.EXTRA_TEXT, "Body");
    try {
        startActivity(Intent.createChooser(intent, "Send mail..."));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(MainActivity.this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
    }
}

1
Bella soluzione! Evita molte applicazioni inadatte (utilizzate principalmente come "Condividi"). Non aggiungere intent.type = "message/rfc822"; intent.type = "text/html";qui in quanto porterà a un'eccezione.
CoolMind

3

È così che l'ho fatto. Bello e semplice.

String emailUrl = "mailto:email@example.com?subject=Subject Text&body=Body Text";
        Intent request = new Intent(Intent.ACTION_VIEW);
        request.setData(Uri.parse(emailUrl));
        startActivity(request);

3

Questa funzione dirige direttamente Gmail per l'invio di e-mail, se gmail non viene trovato, promuovi il selettore di intenti. Ho usato questa funzione in molte app commerciali e funziona benissimo. Spero che ti possa aiutare:

public static void sentEmail(Context mContext, String[] addresses, String subject, String body) {

    try {
        Intent sendIntentGmail = new Intent(Intent.ACTION_VIEW);
        sendIntentGmail.setType("plain/text");
        sendIntentGmail.setData(Uri.parse(TextUtils.join(",", addresses)));
        sendIntentGmail.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
        sendIntentGmail.putExtra(Intent.EXTRA_EMAIL, addresses);
        if (subject != null) sendIntentGmail.putExtra(Intent.EXTRA_SUBJECT, subject);
        if (body != null) sendIntentGmail.putExtra(Intent.EXTRA_TEXT, body);
        mContext.startActivity(sendIntentGmail);
    } catch (Exception e) {
        //When Gmail App is not installed or disable
        Intent sendIntentIfGmailFail = new Intent(Intent.ACTION_SEND);
        sendIntentIfGmailFail.setType("*/*");
        sendIntentIfGmailFail.putExtra(Intent.EXTRA_EMAIL, addresses);
        if (subject != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_SUBJECT, subject);
        if (body != null) sendIntentIfGmailFail.putExtra(Intent.EXTRA_TEXT, body);
        if (sendIntentIfGmailFail.resolveActivity(mContext.getPackageManager()) != null) {
            mContext.startActivity(sendIntentIfGmailFail);
        }
    }
}

1
Molte grazie. Salvami la vita
androCoder-BD,

2

prova semplicemente questo

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    buttonSend = (Button) findViewById(R.id.buttonSend);
    textTo = (EditText) findViewById(R.id.editTextTo);
    textSubject = (EditText) findViewById(R.id.editTextSubject);
    textMessage = (EditText) findViewById(R.id.editTextMessage);

    buttonSend.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            String to = textTo.getText().toString();
            String subject = textSubject.getText().toString();
            String message = textMessage.getText().toString();

            Intent email = new Intent(Intent.ACTION_SEND);
            email.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
            // email.putExtra(Intent.EXTRA_CC, new String[]{ to});
            // email.putExtra(Intent.EXTRA_BCC, new String[]{to});
            email.putExtra(Intent.EXTRA_SUBJECT, subject);
            email.putExtra(Intent.EXTRA_TEXT, message);

            // need this to prompts email client only
            email.setType("message/rfc822");

            startActivity(Intent.createChooser(email, "Choose an Email client :"));

        }
    });
}

3
In che modo questo è migliore delle risposte già esistenti al momento della pubblicazione? Sembra solo una copia della risposta accettata racchiusa in un'attività.
Sam,

2

Altre soluzioni possono essere

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.setType("plain/text");
emailIntent.setClassName("com.google.android.gm", "com.google.android.gm.ComposeActivityGmail");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"someone@gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Yo");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Hi");
startActivity(emailIntent);

Supponendo che la maggior parte del dispositivo Android abbia già installata l'app GMail.


@PedroVarela possiamo sempre verificare l'eccezione dell'attività non trovata.
silentsudo,

1
Sì possiamo. Ma la tua soluzione non è quella giusta. La documentazione di Android indica chiaramente cosa devi fare per mostrare solo le app di posta nel selettore di intenti. Hai scritto "Supponendo che la maggior parte del dispositivo Android abbia già installata l'app Gmail"; Cosa succede se si tratta di un dispositivo rooted e l'utente elimina il client Gmail ?. Supponiamo che tu stia creando la tua app di posta elettronica ?, se un utente sta per inviare un'e-mail, la tua app non sarà in tale elenco. Cosa succede se Gmail modifica il nome del pacchetto? Stai per aggiornare la tua app?
Pedro Varela,

2

Usa questo per inviare e-mail ...

boolean success = EmailIntentBuilder.from(activity)
    .to("support@example.org")
    .cc("developer@example.org")
    .subject("Error report")
    .body(buildErrorReport())
    .start();

usa il livello build:

compile 'de.cketti.mailto:email-intent-builder:1.0.0'

2

Ho usato questo codice per inviare la posta avviando direttamente la sezione di composizione dell'app di posta predefinita.

    Intent i = new Intent(Intent.ACTION_SENDTO);
    i.setType("message/rfc822"); 
    i.setData(Uri.parse("mailto:"));
    i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"test@gmail.com"});
    i.putExtra(Intent.EXTRA_SUBJECT, "Subject");
    i.putExtra(Intent.EXTRA_TEXT   , "body of email");
    try {
        startActivity(Intent.createChooser(i, "Send mail..."));
    } catch (android.content.ActivityNotFoundException ex) {
        Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
    }

1

Questo metodo funziona per me. Apre l'app Gmail (se installata) e imposta mailto.

public void openGmail(Activity activity) {
    Intent emailIntent = new Intent(Intent.ACTION_VIEW);
    emailIntent.setType("text/plain");
    emailIntent.setType("message/rfc822");
    emailIntent.setData(Uri.parse("mailto:"+activity.getString(R.string.mail_to)));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, activity.getString(R.string.app_name) + " - info ");
    final PackageManager pm = activity.getPackageManager();
    final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
    ResolveInfo best = null;
    for (final ResolveInfo info : matches)
        if (info.activityInfo.packageName.endsWith(".gm") || info.activityInfo.name.toLowerCase().contains("gmail"))
            best = info;
    if (best != null)
        emailIntent.setClassName(best.activityInfo.packageName, best.activityInfo.name);
    activity.startActivity(emailIntent);
}

1
/**
 * Will start the chosen Email app
 *
 * @param context    current component context.
 * @param emails     Emails you would like to send to.
 * @param subject    The subject that will be used in the Email app.
 * @param forceGmail True - if you want to open Gmail app, False otherwise. If the Gmail
 *                   app is not installed on this device a chooser will be shown.
 */
public static void sendEmail(Context context, String[] emails, String subject, boolean forceGmail) {

    Intent i = new Intent(Intent.ACTION_SENDTO);
    i.setData(Uri.parse("mailto:"));
    i.putExtra(Intent.EXTRA_EMAIL, emails);
    i.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (forceGmail && isPackageInstalled(context, "com.google.android.gm")) {
        i.setPackage("com.google.android.gm");
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    } else {
        try {
            context.startActivity(Intent.createChooser(i, "Send mail..."));
        } catch (ActivityNotFoundException e) {
            Toast.makeText(context, "No email app is installed on your device...", Toast.LENGTH_SHORT).show();
        }
    }
}

/**
 * Check if the given app is installed on this devuice.
 *
 * @param context     current component context.
 * @param packageName The package name you would like to check.
 * @return True if this package exist, otherwise False.
 */
public static boolean isPackageInstalled(@NonNull Context context, @NonNull String packageName) {
    PackageManager pm = context.getPackageManager();
    if (pm != null) {
        try {
            pm.getPackageInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
    }
    return false;
}

1
 Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(
            "mailto","ebgsoldier@gmail.com", null));
    emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Forgot Password");
    emailIntent.putExtra(Intent.EXTRA_TEXT, "Write your Pubg user name or Phone Number");
    startActivity(Intent.createChooser(emailIntent, "Send email..."));**strong text**

1

Prova questo:

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
}

Il codice sopra aprirà il client di posta elettronica preferito degli utenti precompilato con l'e-mail pronta per l'invio.

fonte

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.