698 votes

Envoi d'e-mails sous Android à l'aide de l'API JavaMail sans utiliser l'application intégrée par défaut

J'essaie de créer une application d'envoi de courrier sous Android.

Si j'utilise :

Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);

Cela lancera l'application Android intégrée ; j'essaie d'envoyer le courrier en cliquant directement sur le bouton. sans en utilisant cette application.

3 votes

Javax.mail.AuthenticationFailedException lors de l'envoi d'un courriel alors que l'utilisateur et le mot de passe sont corrects. Une solution ?

1 votes

Notez que depuis la version 1.5.5, JavaMail prétend prendre en charge Android.

1 votes

N'est-ce pas ? SendGrid une option ? Pour autant que je sache, vous avez également la possibilité d'obtenir des statistiques sur les e-mails que vous envoyez.

789voto

Vinayak B Points 16555

Envoyez des e-mails dans Android à l'aide de l'API JavaMail en utilisant l'authentification Gmail.

Étapes pour créer un projet type :

MailSenderActivity.java :

public class MailSenderActivity extends Activity {

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

        final Button send = (Button) this.findViewById(R.id.send);
        send.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                try {   
                    GMailSender sender = new GMailSender("username@gmail.com", "password");
                    sender.sendMail("This is Subject",   
                            "This is Body",   
                            "user@gmail.com",   
                            "user@yahoo.com");   
                } catch (Exception e) {   
                    Log.e("SendMail", e.getMessage(), e);   
                } 

            }
        });

    }
}

GMailSender.java :

public class GMailSender extends javax.mail.Authenticator {   
    private String mailhost = "smtp.gmail.com";   
    private String user;   
    private String password;   
    private Session session;   

    static {   
        Security.addProvider(new com.provider.JSSEProvider());   
    }  

    public GMailSender(String user, String password) {   
        this.user = user;   
        this.password = password;   

        Properties props = new Properties();   
        props.setProperty("mail.transport.protocol", "smtp");   
        props.setProperty("mail.host", mailhost);   
        props.put("mail.smtp.auth", "true");   
        props.put("mail.smtp.port", "465");   
        props.put("mail.smtp.socketFactory.port", "465");   
        props.put("mail.smtp.socketFactory.class",   
                "javax.net.ssl.SSLSocketFactory");   
        props.put("mail.smtp.socketFactory.fallback", "false");   
        props.setProperty("mail.smtp.quitwait", "false");   

        session = Session.getDefaultInstance(props, this);   
    }   

    protected PasswordAuthentication getPasswordAuthentication() {   
        return new PasswordAuthentication(user, password);   
    }   

    public synchronized void sendMail(String subject, String body, String sender, String recipients) throws Exception {   
        try{
        MimeMessage message = new MimeMessage(session);   
        DataHandler handler = new DataHandler(new ByteArrayDataSource(body.getBytes(), "text/plain"));   
        message.setSender(new InternetAddress(sender));   
        message.setSubject(subject);   
        message.setDataHandler(handler);   
        if (recipients.indexOf(',') > 0)   
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipients));   
        else  
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(recipients));   
        Transport.send(message);   
        }catch(Exception e){

        }
    }   

    public class ByteArrayDataSource implements DataSource {   
        private byte[] data;   
        private String type;   

        public ByteArrayDataSource(byte[] data, String type) {   
            super();   
            this.data = data;   
            this.type = type;   
        }   

        public ByteArrayDataSource(byte[] data) {   
            super();   
            this.data = data;   
        }   

        public void setType(String type) {   
            this.type = type;   
        }   

        public String getContentType() {   
            if (type == null)   
                return "application/octet-stream";   
            else  
                return type;   
        }   

        public InputStream getInputStream() throws IOException {   
            return new ByteArrayInputStream(data);   
        }   

        public String getName() {   
            return "ByteArrayDataSource";   
        }   

        public OutputStream getOutputStream() throws IOException {   
            throw new IOException("Not Supported");   
        }   
    }   
}  

JSSEProvider.java :

/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * @author Alexander Y. Kleymenov
 * @version $Revision$
 */

import java.security.AccessController;
import java.security.Provider;

public final class JSSEProvider extends Provider {

    public JSSEProvider() {
        super("HarmonyJSSE", 1.0, "Harmony JSSE Provider");
        AccessController.doPrivileged(new java.security.PrivilegedAction<Void>() {
            public Void run() {
                put("SSLContext.TLS",
                        "org.apache.harmony.xnet.provider.jsse.SSLContextImpl");
                put("Alg.Alias.SSLContext.TLSv1", "TLS");
                put("KeyManagerFactory.X509",
                        "org.apache.harmony.xnet.provider.jsse.KeyManagerFactoryImpl");
                put("TrustManagerFactory.X509",
                        "org.apache.harmony.xnet.provider.jsse.TrustManagerFactoryImpl");
                return null;
            }
        });
    }
}

AJOUTEZ 3 bocaux trouvés dans le lien suivant à votre projet Android

Cliquez ici - Comment ajouter des jarres externes

Et n'oubliez pas d'ajouter cette ligne dans votre manifeste :

<uses-permission android:name="android.permission.INTERNET" />

Cliquez simplement sur le lien ci-dessous pour modifier l'accès au compte pour les applications moins sécurisées. https://www.google.com/settings/security/lesssecureapps

Exécutez le projet et vérifiez que votre compte de messagerie destinataire a bien reçu le courrier. A la vôtre !

P.S. Et n'oubliez pas que vous ne pouvez pas faire d'opération réseau à partir de n'importe quelle activité dans Android. Il est donc recommandé d'utiliser AsyncTask ou IntentService pour éviter l'exception du réseau sur le fil principal.

Fichiers jar : https://code.google.com/archive/p/javamail-Android/

56 votes

Votre code semble utiliser un nom d'utilisateur et un mot de passe codés en dur. Est-ce que cela présente actuellement un risque de sécurité (c'est-à-dire que les apk qui sont téléchargés sur le marché ont été décompilés) ?

11 votes

Cela fonctionne pour moi !!! n'oubliez pas d'ajouter à votre manifeste d'application la permission d'utilisation INTERNET.

6 votes

Vous avez un problème dans GMailSender.sendMail(). Le problème est qu'aucune erreur ne sort de sendMail parce que vous avez try..catch à l'intérieur qui entoure tout le code. Vous devriez supprimer try..catch de sendMail. Sinon, il est impossible de détecter les erreurs

73voto

ashok reddy Points 353

Merci pour vos précieuses informations. Le code fonctionne bien. Je suis capable d'ajouter une pièce jointe en ajoutant le code suivant.

private Multipart _multipart; 
_multipart = new MimeMultipart(); 

public void addAttachment(String filename,String subject) throws Exception { 
    BodyPart messageBodyPart = new MimeBodyPart(); 
    DataSource source = new FileDataSource(filename); 
    messageBodyPart.setDataHandler(new DataHandler(source)); 
    messageBodyPart.setFileName(filename); 
    _multipart.addBodyPart(messageBodyPart);

    BodyPart messageBodyPart2 = new MimeBodyPart(); 
    messageBodyPart2.setText(subject); 

    _multipart.addBodyPart(messageBodyPart2); 
} 

message.setContent(_multipart);

6 votes

Ajoutez ceci à GmailSender.java

0 votes

Quand j'ai appelé setcontent, il a écrasé le contenu du corps. Est-ce que je fais quelque chose de mal ? Je veux ajouter une pièce jointe avec un autre contenu textuel du corps.

1 votes

Pour filename ici, vous devez spécifier le chemin du fichier. Par exemple : String path = Environment.getExternalStorageDirectory().getPath() + "/temp_share.jpg";

58voto

ManuV Points 389

Impossible de se connecter à l'hôte SMTP : smtp.gmail.com, port : 465

Ajoutez cette ligne dans votre manifeste :

<uses-permission android:name="android.permission.INTERNET" />

40voto

Funkyidol Points 1897

Vous pouvez utiliser l'API JavaMail pour gérer vos tâches de courrier électronique. L'API JavaMail est disponible dans le package JavaEE et son jar est disponible au téléchargement. Malheureusement, elle ne peut pas être utilisée directement dans une application Android car elle utilise des composants AWT qui sont totalement incompatibles avec Android.

Vous pouvez trouver le port Android pour JavaMail à l'emplacement suivant : http://code.google.com/p/javamail-Android/

Ajoutez les jars à votre application et utilisez la méthode SMTP.

1 votes

Y a-t-il un dépôt maven pour cela ?

0 votes

Désolé mais je ne suis pas au courant de cela

6 votes

J'ai porté la dernière version de JavaMail et elle est disponible sur Maven Central dans la rubrique eu.ocathain.com.sun.mail:javax.mail:1.5.2

31voto

Ryan Heitner Points 1586

Afin d'aider ceux qui obtiennent une exception Network On Main Thread avec une cible SDK >9. Ceci utilise le code de Droopie ci-dessus mais fonctionnera de la même manière pour n'importe quel autre.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 

android.os.NetworkOnMainThreadException

Vous pouvez utiliser AsyncTask comme suit

public void onClickMail(View view) {
    new SendEmailAsyncTask().execute();
}

class SendEmailAsyncTask extends AsyncTask <Void, Void, Boolean> {
    Mail m = new Mail("from@gmail.com", "my password");

    public SendEmailAsyncTask() {
        if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "SendEmailAsyncTask()");
        String[] toArr = { "to mail@gmail.com"};
        m.setTo(toArr);
        m.setFrom("from mail@gmail.com");
        m.setSubject("Email from Android");
        m.setBody("body.");
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        if (BuildConfig.DEBUG) Log.v(SendEmailAsyncTask.class.getName(), "doInBackground()");
        try {
            m.send();
            return true;
        } catch (AuthenticationFailedException e) {
            Log.e(SendEmailAsyncTask.class.getName(), "Bad account details");
            e.printStackTrace();
            return false;
        } catch (MessagingException e) {
            Log.e(SendEmailAsyncTask.class.getName(), m.getTo(null) + "failed");
            e.printStackTrace();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X