Come posso inviare e-mail dalla mia applicazione Android?


Answers

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

Question

Sto scrivendo un'applicazione per Android. Come posso inviare una e-mail da questo?




Questo è come 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);



Un'altra soluzione può 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.




Io uso il codice qui sotto nelle mie app. Questo mostra esattamente le app del 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)));



Ho usato questo codice per inviare posta avviando direttamente la sezione di composizione delle 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();
    }



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

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

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 intento ACTION_SENDTO per protocollo (che sono solo app di posta elettronica) e costruisce un selettore basato su quell'elenco di attività e l'intento originale di ACTION_SEND con il tipo mime corretto.

Un altro vantaggio è che Skype non è più elencato (il che accade per rispondere al tipo mime rfc822).




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

Utilizzando ACTION_SENDTO e un mailto: URI sembra funzionare perfettamente ed è raccomandato nella documentazione per sviluppatori . Tuttavia, se si esegue questa operazione sugli emulatori ufficiali e non ci sono account di posta elettronica impostati (o non ci sono client di posta), si ottiene il seguente errore:

Azione non supportata

Questa azione non è attualmente supportata.

Come mostrato di seguito:

Risulta che gli emulatori risolvono l'intenzione di un'attività chiamata com.android.fallback.Fallback , che visualizza il messaggio precedente. Apparentemente questo è di design.

Se vuoi che la tua app elimini questa funzione, in modo che funzioni correttamente anche sugli emulatori ufficiali, puoi verificarla prima di provare a inviare l'email:

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 sviluppatori .




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 )

Il più importante è il flag: è ACTION_SENDTO e non ACTION_SEND

L'altra linea importante è

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

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

Secondo la documentazione di Android. Se vuoi assicurarti che il tuo intento sia gestito solo da un'app di posta elettronica (e non da altre app di messaggistica di testo o social), usa l'azione ACTION_SENDTO e includi lo schema di dati " mailto: ". 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);
    }
}



Questa funzione è diretta innanzitutto a intendere Gmail per l'invio di e-mail, se non si trova Gmail, quindi promuovere l'intento di selezione. Ho usato questa funzione in molte app commerciali e funziona bene. Spero 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);
        }
    }
}



Related