program story

기본 / 내장 앱을 사용하지 않고 JavaMail API를 사용하여 Android에서 이메일 보내기

inputbox 2020. 10. 2. 22:14
반응형

기본 / 내장 앱을 사용하지 않고 JavaMail API를 사용하여 Android에서 이메일 보내기


Android에서 메일 발송 애플리케이션을 만들려고합니다.

내가 사용하는 경우 :

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

내장 Android 애플리케이션이 시작됩니다. 이 응용 프로그램 사용 하지 않고 직접 버튼 클릭으로 메일을 보내려고 합니다.


Gmail 인증을 사용하여 JavaMail API를 사용하여 Android에서 이메일을 보냅니다.

샘플 프로젝트를 만드는 단계 :

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

다음 링크에있는 3 개의 jar를 Android 프로젝트에 추가하십시오.

여기를 클릭하십시오-외부 항아리를 추가하는 방법

매니페스트에 다음 줄을 추가하는 것을 잊지 마십시오.

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

보안 수준이 낮은 앱 https://www.google.com/settings/security/lesssecureapps에 대한 계정 액세스를 변경하려면 아래 링크를 클릭 하세요.

프로젝트를 실행하고 수신자 메일 계정에서 메일을 확인하십시오. 건배!

추신 그리고 안드로이드의 어떤 활동에서도 네트워크 작업을 할 수 없다는 것을 잊지 마십시오. 따라서 주 스레드 예외에서 네트워크 를 사용 AsyncTask하거나 IntentService피하는 것이 좋습니다 .

Jar 파일 : https://code.google.com/archive/p/javamail-android/


귀중한 정보에 감사드립니다. 코드가 잘 작동합니다. 다음 코드를 추가하여 첨부 파일을 추가 할 수도 있습니다.

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

SMTP 호스트 : smtp.gmail.com, 포트 : 465에 연결할 수 없습니다.

매니페스트에 다음 줄을 추가합니다.

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

JavaMail API를 사용하여 이메일 작업을 처리 할 수 ​​있습니다. JavaMail API는 JavaEE 패키지에서 사용할 수 있으며 해당 jar는 다운로드 할 수 있습니다. 안타깝게도 Android에서 완전히 호환되지 않는 AWT 구성 요소를 사용하기 때문에 Android 애플리케이션에서 직접 사용할 수 없습니다.

다음 위치에서 JavaMail 용 Android 포트를 찾을 수 있습니다. http://code.google.com/p/javamail-android/

애플리케이션에 jar를 추가하고 SMTP 방법을 사용합니다.


SDK Target> 9로 Network On Main Thread Exception을받는 사람들을 돕기 위해. 이것은 위의 droopie의 코드를 사용하고 있지만 유사하게 작동합니다.

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

StrictMode.setThreadPolicy(policy); 

android.os.NetworkOnMainThreadException

AsyncTask를 아래와 같이 사용할 수 있습니다.

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

SMTP

SMTP를 사용하는 것이 하나의 방법이며 다른 방법은 이미 방법을 지적했습니다. 이 작업을 수행하는 동안 기본 제공 메일 앱을 완전히 우회하게되며, SMTP 서버의 주소, 해당 서버의 사용자 이름 및 비밀번호를 코드에 정적으로 제공하거나 사용자로부터 쿼리해야합니다. .

HTTP

또 다른 방법은 php와 같은 간단한 서버 측 스크립트를 사용하여 일부 URL 매개 변수를 가져 와서 메일을 보내는 데 사용합니다. 이렇게하면 장치에서 HTTP 요청 만 수행하면되고 (내장 된 라이브러리로 쉽게 가능) 장치에 SMTP 로그인 데이터를 저장할 필요가 없습니다. 이것은 직접적인 SMTP 사용에 비해 간접적이지만 HTTP 요청을 만들고 PHP에서 메일을 보내는 것이 매우 쉽기 때문에 직접적인 방법보다 더 간단 할 수도 있습니다.

메일 신청

메일이 이미 전화에 등록 된 사용자 기본 메일 계정에서 전송되는 경우 다른 접근 방식을 취해야합니다. 충분한 시간과 경험이 있다면 Android 이메일 애플리케이션의 소스 코드를 확인하여 사용자 상호 작용없이 메일을 보낼 수있는 진입 점을 제공하는지 확인할 수 있습니다 (모르지만있을 수 있습니다).

사용자 계정 세부 정보를 쿼리하는 방법을 찾을 수도 있지만 (SMTP에 사용할 수 있도록), 이것이 가능한지 매우 의심 스럽습니다. 왜냐하면 엄청난 보안 위험이 있고 Android가 다소 안전하게 구축 되었기 때문입니다.


데모로 100 % 작동하는 코드이 답변을 사용하여 여러 이메일을 보낼 수도 있습니다.

여기에서 프로젝트 다운로드

1 단계 : 메일, 활성화, 추가 jar 파일을 다운로드 하고 Android 스튜디오 프로젝트 libs 폴더추가합니다 . 스크린 샷을 추가했습니다. 다운로드 링크 참조

libs 추가

Gmail로 로그인 ( from mail 사용 ) 및 TURN ON 토글 버튼 LINK

대부분의 사람들이이 단계를 잊어 버리지 않기를 바랍니다.

2 단계 : 이 프로세스를 완료 한 후. 이 클래스를 프로젝트에 복사하여 붙여 넣으십시오.

GMail.java

import android.util.Log;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class GMail {

    final String emailPort = "587";// gmail's smtp port
    final String smtpAuth = "true";
    final String starttls = "true";
    final String emailHost = "smtp.gmail.com";


    String fromEmail;
    String fromPassword;
    List<String> toEmailList;
    String emailSubject;
    String emailBody;

    Properties emailProperties;
    Session mailSession;
    MimeMessage emailMessage;

    public GMail() {

    }

    public GMail(String fromEmail, String fromPassword,
            List<String> toEmailList, String emailSubject, String emailBody) {
        this.fromEmail = fromEmail;
        this.fromPassword = fromPassword;
        this.toEmailList = toEmailList;
        this.emailSubject = emailSubject;
        this.emailBody = emailBody;

        emailProperties = System.getProperties();
        emailProperties.put("mail.smtp.port", emailPort);
        emailProperties.put("mail.smtp.auth", smtpAuth);
        emailProperties.put("mail.smtp.starttls.enable", starttls);
        Log.i("GMail", "Mail server properties set.");
    }

    public MimeMessage createEmailMessage() throws AddressException,
            MessagingException, UnsupportedEncodingException {

        mailSession = Session.getDefaultInstance(emailProperties, null);
        emailMessage = new MimeMessage(mailSession);

        emailMessage.setFrom(new InternetAddress(fromEmail, fromEmail));
        for (String toEmail : toEmailList) {
            Log.i("GMail", "toEmail: " + toEmail);
            emailMessage.addRecipient(Message.RecipientType.TO,
                    new InternetAddress(toEmail));
        }

        emailMessage.setSubject(emailSubject);
        emailMessage.setContent(emailBody, "text/html");// for a html email
        // emailMessage.setText(emailBody);// for a text email
        Log.i("GMail", "Email Message created.");
        return emailMessage;
    }

    public void sendEmail() throws AddressException, MessagingException {

        Transport transport = mailSession.getTransport("smtp");
        transport.connect(emailHost, fromEmail, fromPassword);
        Log.i("GMail", "allrecipients: " + emailMessage.getAllRecipients());
        transport.sendMessage(emailMessage, emailMessage.getAllRecipients());
        transport.close();
        Log.i("GMail", "Email sent successfully.");
    }

}

SendMailTask.java

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;

import java.util.List;

public class SendMailTask extends AsyncTask {

    private ProgressDialog statusDialog;
    private Activity sendMailActivity;

    public SendMailTask(Activity activity) {
        sendMailActivity = activity;

    }

    protected void onPreExecute() {
        statusDialog = new ProgressDialog(sendMailActivity);
        statusDialog.setMessage("Getting ready...");
        statusDialog.setIndeterminate(false);
        statusDialog.setCancelable(false);
        statusDialog.show();
    }

    @Override
    protected Object doInBackground(Object... args) {
        try {
            Log.i("SendMailTask", "About to instantiate GMail...");
            publishProgress("Processing input....");
            GMail androidEmail = new GMail(args[0].toString(),
                    args[1].toString(), (List) args[2], args[3].toString(),
                    args[4].toString());
            publishProgress("Preparing mail message....");
            androidEmail.createEmailMessage();
            publishProgress("Sending email....");
            androidEmail.sendEmail();
            publishProgress("Email Sent.");
            Log.i("SendMailTask", "Mail Sent.");
        } catch (Exception e) {
            publishProgress(e.getMessage());
            Log.e("SendMailTask", e.getMessage(), e);
        }
        return null;
    }

    @Override
    public void onProgressUpdate(Object... values) {
        statusDialog.setMessage(values[0].toString());

    }

    @Override
    public void onPostExecute(Object result) {
        statusDialog.dismiss();
    }

}

3 단계 : 이제 필요에 따라이 클래스를 변경할 수 있으며이 클래스를 사용하여 여러 메일을 보낼 수도 있습니다. 나는 xml과 java 파일을 모두 제공합니다.

activity_mail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="30dp">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="From Email" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:cursorVisible="true"
        android:editable="true"
        android:ems="10"
        android:enabled="true"
        android:inputType="textEmailAddress"
        android:padding="5dp"
        android:textColor="#000000">

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="Password (For from email)" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FFFFFF"
        android:ems="10"
        android:inputType="textPassword"
        android:padding="5dp"
        android:textColor="#000000" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="To Email" />

    <EditText
        android:id="@+id/editText3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:ems="10"
        android:inputType="textEmailAddress"
        android:padding="5dp"
        android:textColor="#000000" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="Subject" />

    <EditText
        android:id="@+id/editText4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:ems="10"
        android:padding="5dp"
        android:textColor="#000000" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:text="Body" />

    <EditText
        android:id="@+id/editText5"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ffffff"
        android:ems="10"
        android:inputType="textMultiLine"
        android:padding="35dp"
        android:textColor="#000000" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Email" />

</LinearLayout>

SendMailActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Arrays;
import java.util.List;

public class SendMailActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final Button send = (Button) this.findViewById(R.id.button1);

        send.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                Log.i("SendMailActivity", "Send Button Clicked.");

                String fromEmail = ((TextView) findViewById(R.id.editText1))
                        .getText().toString();
                String fromPassword = ((TextView) findViewById(R.id.editText2))
                        .getText().toString();
                String toEmails = ((TextView) findViewById(R.id.editText3))
                        .getText().toString();
                List<String> toEmailList = Arrays.asList(toEmails
                        .split("\\s*,\\s*"));
                Log.i("SendMailActivity", "To List: " + toEmailList);
                String emailSubject = ((TextView) findViewById(R.id.editText4))
                        .getText().toString();
                String emailBody = ((TextView) findViewById(R.id.editText5))
                        .getText().toString();
                new SendMailTask(SendMailActivity.this).execute(fromEmail,
                        fromPassword, toEmailList, emailSubject, emailBody);
            }
        });
    }
}

참고 AndroidManifest.xml 파일에 인터넷 권한 을 추가하는 것을 잊지 마십시오.

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

그렇지 않으면 아래에 댓글을 달아주세요.


여기에 저에게도 작동하고 첨부 파일이있는 대체 버전이 있습니다 (이미 위에 게시되었지만 소스 링크와 달리 완전한 버전, 사람들이 게시 한 데이터가 없어서 작동하지 못함)

import java.util.Date; 
import java.util.Properties; 
import javax.activation.CommandMap; 
import javax.activation.DataHandler; 
import javax.activation.DataSource; 
import javax.activation.FileDataSource; 
import javax.activation.MailcapCommandMap; 
import javax.mail.BodyPart; 
import javax.mail.Multipart; 
import javax.mail.PasswordAuthentication; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeMultipart; 


public class Mail extends javax.mail.Authenticator { 
  private String _user; 
  private String _pass; 

  private String[] _to; 
  private String _from; 

  private String _port; 
  private String _sport; 

  private String _host; 

  private String _subject; 
  private String _body; 

  private boolean _auth; 

  private boolean _debuggable; 

  private Multipart _multipart; 


  public Mail() { 
    _host = "smtp.gmail.com"; // default smtp server 
    _port = "465"; // default smtp port 
    _sport = "465"; // default socketfactory port 

    _user = ""; // username 
    _pass = ""; // password 
    _from = ""; // email sent from 
    _subject = ""; // email subject 
    _body = ""; // email body 

    _debuggable = false; // debug mode on or off - default off 
    _auth = true; // smtp authentication - default on 

    _multipart = new MimeMultipart(); 

    // There is something wrong with MailCap, javamail can not find a handler for the multipart/mixed part, so this bit needs to be added. 
    MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
    mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
    mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
    mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain"); 
    mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
    mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822"); 
    CommandMap.setDefaultCommandMap(mc); 
  } 

  public Mail(String user, String pass) { 
    this(); 

    _user = user; 
    _pass = pass; 
  } 

  public boolean send() throws Exception { 
    Properties props = _setProperties(); 

    if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") && !_subject.equals("") && !_body.equals("")) { 
      Session session = Session.getInstance(props, this); 

      MimeMessage msg = new MimeMessage(session); 

      msg.setFrom(new InternetAddress(_from)); 

      InternetAddress[] addressTo = new InternetAddress[_to.length]; 
      for (int i = 0; i < _to.length; i++) { 
        addressTo[i] = new InternetAddress(_to[i]); 
      } 
        msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

      msg.setSubject(_subject); 
      msg.setSentDate(new Date()); 

      // setup message body 
      BodyPart messageBodyPart = new MimeBodyPart(); 
      messageBodyPart.setText(_body); 
      _multipart.addBodyPart(messageBodyPart); 

      // Put parts in message 
      msg.setContent(_multipart); 

      // send email 
      Transport.send(msg); 

      return true; 
    } else { 
      return false; 
    } 
  } 

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

    _multipart.addBodyPart(messageBodyPart); 
  } 

  @Override 
  public PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(_user, _pass); 
  } 

  private Properties _setProperties() { 
    Properties props = new Properties(); 

    props.put("mail.smtp.host", _host); 

    if(_debuggable) { 
      props.put("mail.debug", "true"); 
    } 

    if(_auth) { 
      props.put("mail.smtp.auth", "true"); 
    } 

    props.put("mail.smtp.port", _port); 
    props.put("mail.smtp.socketFactory.port", _sport); 
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
    props.put("mail.smtp.socketFactory.fallback", "false"); 

    return props; 
  } 

  // the getters and setters 
  public String getBody() { 
    return _body; 
  } 

  public void setBody(String _body) { 
    this._body = _body; 
  }

  public void setTo(String[] toArr) {
      // TODO Auto-generated method stub
      this._to=toArr;
  }

  public void setFrom(String string) {
      // TODO Auto-generated method stub
      this._from=string;
  }

  public void setSubject(String string) {
      // TODO Auto-generated method stub
      this._subject=string;
  }  

  // more of the getters and setters ….. 
}

그리고 그것을 활동이라고 부르기 위해 ...

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

  Button addImage = (Button) findViewById(R.id.send_email); 
  addImage.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View view) { 
      Mail m = new Mail("gmailusername@gmail.com", "password"); 

      String[] toArr = {"bla@bla.com", "lala@lala.com"}; 
      m.setTo(toArr); 
      m.setFrom("wooo@wooo.com"); 
      m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device."); 
      m.setBody("Email body."); 

      try { 
        m.addAttachment("/sdcard/filelocation"); 

        if(m.send()) { 
          Toast.makeText(MailApp.this, "Email was sent successfully.", Toast.LENGTH_LONG).show(); 
        } else { 
          Toast.makeText(MailApp.this, "Email was not sent.", Toast.LENGTH_LONG).show(); 
        } 
      } catch(Exception e) { 
        //Toast.makeText(MailApp.this, "There was a problem sending the email.", Toast.LENGTH_LONG).show(); 
        Log.e("MailApp", "Could not send email", e); 
      } 
    } 
  }); 
} 

"smtp.gmail.com"을 기본 SMTP 서버로 사용하는 경우 경고의 말씀입니다.

Google은 과도한 "의심스러운 활동"정책으로 인해 연결된 이메일 계정 비밀번호를 자주 변경하도록 강제 할 것입니다. 본질적으로 짧은 시간 내에 여러 국가에서 반복되는 smtp 요청을 "의심스러운 활동"으로 취급합니다. 귀하 (이메일 계정 소유자)는 한 번에 한 국가에만있을 수 있다고 가정합니다.

Google 시스템이 "의심스러운 활동"을 감지하면 비밀번호를 변경할 때까지 추가 이메일을 차단합니다. 앱에 암호를 하드 코딩 했으므로 이런 일이 발생할 때마다 앱을 다시 릴리스해야합니다. 이상적이지는 않습니다. 이것은 나에게 일주일에 세 번 발생했으며 다른 서버에 비밀번호를 저장하고 Google에서 강제로 비밀번호를 변경할 때마다 비밀번호를 동적으로 가져 왔습니다.

따라서이 보안 문제를 방지하려면 "smtp.gmail.com"대신 많은 무료 smtp 제공 업체 중 하나를 사용하는 것이 좋습니다. 동일한 코드를 사용하되 "smtp.gmail.com"을 새 smtp 전달 호스트로 변경합니다.


GmailBackground는 사용자 상호 작용없이 백그라운드에서 이메일을 보내는 작은 라이브러리입니다.

용법:

    BackgroundMail.newBuilder(this)
            .withUsername("username@gmail.com")
            .withPassword("password12345")
            .withMailto("toemail@gmail.com")
            .withType(BackgroundMail.TYPE_PLAIN)
            .withSubject("this is the subject")
            .withBody("this is the body")
            .withOnSuccessCallback(new BackgroundMail.OnSuccessCallback() {
                @Override
                public void onSuccess() {
                    //do some magic
                }
            })
            .withOnFailCallback(new BackgroundMail.OnFailCallback() {
                @Override
                public void onFail() {
                    //do some magic
                }
            })
            .send();

구성 :

repositories {
    // ...
    maven { url "https://jitpack.io" }
 }
 dependencies {
            compile 'com.github.yesidlazaro:GmailBackground:1.2.0'
    }

권한 :

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

또한 첨부 파일의 경우 READ_EXTERNAL_STORAGE 권한을 설정해야합니다.

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

출처

(내가 직접 테스트했습니다)


편집 : JavaMail 1.5.5 는 Android를 지원한다고 주장 하므로 다른 것이 필요하지 않습니다.

최신 JavaMail (1.5.4)을 Android로 이식했습니다. Maven Central에서 사용할 수 있습니다. build.gradle~~에 다음을 추가하십시오.

compile 'eu.ocathain.com.sun.mail:javax.mail:1.5.4'

그런 다음 공식 자습서 를 따를 수 있습니다 .

소스 코드는 여기에서 사용할 수 있습니다 : https://bitbucket.org/artbristol/javamail-forked-android


도움이 필요한 다른 사람들을 위해 더 짧은 대안을 찾았습니다. 코드는 다음과 같습니다.

package com.example.mail;

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendMailTLS {

    public static void main(String[] args) {

        final String username = "username@gmail.com";
        final String password = "password";

        Properties props = new Properties();
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "587");

        Session session = Session.getInstance(props,
          new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("username", "password");
            }
          });

        try {

            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("from-email@gmail.com"));
            message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("to-email@gmail.com"));
            message.setSubject("Testing Subject");
            message.setText("Dear Mail Crawler,"
                + "\n\n No spam to my email, please!");

            Transport.send(message);

            System.out.println("Done");

        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
}

출처 : JavaMail API를 통해 이메일 보내기

도움이 되었기를 바랍니다! 행운을 빕니다!


ClassDefNotFoundError세 개의 jar 파일을 프로젝트의 lib 폴더로 옮기려 는 사람들은 나를 위해 일했습니다!


첨부 파일이있는 메일 발송 용 ..

public class SendAttachment{
                    public static void main(String [] args){ 
             //to address
                    String to="abc@abc.com";//change accordingly
                    //from address
                    final String user="efg@efg.com";//change accordingly
                    final String password="password";//change accordingly 
                     MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap();
                   mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
                  mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
                  mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
                  mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
                  mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
                  CommandMap.setDefaultCommandMap(mc); 
                  //1) get the session object   
                  Properties properties = System.getProperties();
                  properties.put("mail.smtp.port", "465"); 
                  properties.put("mail.smtp.host", "smtp.gmail.com");
                    properties.put("mail.smtp.socketFactory.port", "465");
                    properties.put("mail.smtp.socketFactory.class",
                            "javax.net.ssl.SSLSocketFactory");
                    properties.put("mail.smtp.auth", "true");
                    properties.put("mail.smtp.port", "465");

                  Session session = Session.getDefaultInstance(properties,
                   new javax.mail.Authenticator() {
                   protected PasswordAuthentication getPasswordAuthentication() {
                   return new PasswordAuthentication(user,password);
                   }
                  });

                  //2) compose message   
                  try{ 
                    MimeMessage message = new MimeMessage(session);
                    message.setFrom(new InternetAddress(user));
                    message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
                    message.setSubject("Hii"); 
                    //3) create MimeBodyPart object and set your message content    
                    BodyPart messageBodyPart1 = new MimeBodyPart();
                    messageBodyPart1.setText("How is This"); 
                    //4) create new MimeBodyPart object and set DataHandler object to this object    
                    MimeBodyPart messageBodyPart2 = new MimeBodyPart();
                //Location of file to be attached
                    String filename = Environment.getExternalStorageDirectory().getPath()+"/R2832.zip";//change accordingly
                    DataSource source = new FileDataSource(filename);
                    messageBodyPart2.setDataHandler(new DataHandler(source));
                    messageBodyPart2.setFileName("Hello"); 
                    //5) create Multipart object and add MimeBodyPart objects to this object    
                    Multipart multipart = new MimeMultipart();
                    multipart.addBodyPart(messageBodyPart1);
                    multipart.addBodyPart(messageBodyPart2); 
                    //6) set the multiplart object to the message object
                    message.setContent(multipart ); 
                    //7) send message 
                    Transport.send(message); 
                   System.out.println("MESSAGE SENT....");
                   }catch (MessagingException ex) {ex.printStackTrace();}
                  }
                }

Vinayak B의 코드를 실행할 수 없습니다. 마지막으로 다음과 같이이 문제를 해결했습니다.

1. 이것을 사용

2. AsyncTask 적용.

보낸 사람의 Gmail 계정의 보안 문제를 템플릿 3..의 (변경 "전원 켜짐"으로)


Apache Commons Net 사용을 고려하셨습니까? 3.3부터 단지 하나의 jar (그리고 gradle 또는 maven을 사용하여 그것에 의존 할 수 있음) 그리고 당신은 끝났습니다 : http://blog.dahanne.net/2013/06/17/sending-a-mail-in-java- and-android-with-apache-commons-net /


사용자 개입없이 다음과 같이 보낼 수 있습니다.

  1. 클라이언트 apk에서 이메일을 보냅니다. 여기서 mail.jar, activation.jar은 자바 이메일을 보내기 위해 필요합니다. 이러한 jar가 추가되면 APK 크기가 늘어날 수 있습니다.

  2. 또는 동일한 mail.jar 및 activation.jar을 사용하여 이메일을 보내는 서버 측 코드에서 웹 서비스를 사용할 수 있습니다. asynctask를 통해 웹 서비스를 호출하고 이메일을 보낼 수 있습니다. 동일한 링크를 참조하십시오.

(그러나 메일 계정의 자격 증명을 알아야합니다.)


jar 라이브러리를 가능한 한 작게 유지해야하는 경우 "dex에 너무 많은 메서드가 있음"문제를 방지하기 위해 SMTP / POP3 / IMAP 함수를 별도로 포함 할 수 있습니다.

javanet 웹 페이지 에서 원하는 jar 라이브러리를 선택할 수 있습니다. 예를 들어 mailapi.jar + imap.jar을 사용하면 IMAP 프로토콜의 icloud, hotmail 메일 서버에 액세스 할 수 있습니다. (addition.jar 및 activation.jar의 도움으로)


@Vinayak B가 제출 한 코드를 사용해 보았습니다. 그러나 다음과 같은 오류가 발생합니다. smtp에 대한 공급자가 없습니다.

여기에 더 많은 정보를 담은 새로운 질문을 만들었습니다.

결국 나는 그것을 스스로 고칠 수 있었다. 다른 mail.jar 을 사용해야 했고 " 보안 수준이 낮은 앱에 대한 액세스 "가 켜져 있는지 확인해야 했습니다.

나는 이것이 같은 문제를 가진 모든 사람에게 도움이되기를 바랍니다. 이렇게하면이 코드가 Google Glass에서도 작동합니다.


다른 답변에 제공된 모든 코드는 정확하고 잘 작동하지만 약간 지저분하므로 더 쉬운 방법으로 사용하기 위해 라이브러리 (아직 개발 중)를 게시하기로 결정했습니다 : AndroidMail .

MailSender를 생성하고, 메일을 작성하고, 전송하기 만하면됩니다 (이미 AsyncTask를 사용하여 백그라운드에서 처리됨).

MailSender mailSender = new MailSender(email, password);

Mail.MailBuilder builder = new Mail.MailBuilder();
Mail mail = builder
    .setSender(senderMail)
    .addRecipient(new Recipient(recipient))
    .setText("Hello")
    .build();

mailSender.sendMail(mail);

보낸 이메일에 대한 알림을받을 수 있으며 다양한 수신자 유형 (받는 사람, 참조 및 숨은 참조), 첨부 파일 및 html에 대한 지원도 있습니다.

MailSender mailSender = new MailSender(email, password);

Mail.MailBuilder builder = new Mail.MailBuilder();
Mail mail = builder
    .setSender(senderMail)
    .addRecipient(new Recipient(recipient))
    .addRecipient(new Recipient(Recipient.TYPE.CC, recipientCC))
    .setText("Hello")
    .setHtml("<h1 style=\"color:red;\">Hello</h1>")
    .addAttachment(new Attachment(filePath, fileName))
    .build();

mailSender.sendMail(mail, new MailSender.OnMailSentListener() {

    @Override
    public void onSuccess() {
        // mail sent!
    }

    @Override
    public void onError(Exception error) {
        // something bad happened :(
    }
});

Gradle 또는 Maven을 통해 얻을 수 있습니다.

compile 'it.enricocandino:androidmail:1.0.0-SNAPSHOT'

문제가 있으면 알려주세요! :)


 Add jar files mail.jar,activation.jar,additionnal.jar

 String sub="Thank you for your online registration" ; 
 Mail m = new Mail("emailid", "password"); 

 String[] toArr = {"ekkatrainfo@gmail.com",sEmailId};
 m.setFrom("ekkatrainfo@gmail.com"); 

     m.setTo(toArr);
     m.setSubject(sub);
    m.setBody(msg);



                     try{


                            if(m.send()) { 

                            } else { 

                            } 
                          } catch(Exception e) { 

                            Log.e("MailApp", "Could not send email", e); 
                          } 

  package com.example.ekktra;

   import java.util.Date;
   import java.util.Properties;

   import javax.activation.CommandMap;
   import javax.activation.DataHandler;
   import javax.activation.DataSource;
   import javax.activation.FileDataSource;
   import javax.activation.MailcapCommandMap;
   import javax.mail.BodyPart;
   import javax.mail.Multipart;
   import javax.mail.PasswordAuthentication;
   import javax.mail.Session;
   import javax.mail.Transport;
   import javax.mail.internet.InternetAddress;
   import javax.mail.internet.MimeBodyPart;
   import javax.mail.internet.MimeMessage;
   import javax.mail.internet.MimeMultipart;

   public class Mail extends javax.mail.Authenticator { 
     private String _user; 
     private String _pass; 

     private String[] _to; 

     private String _from; 

     private String _port; 
     private String _sport; 

     private String _host; 

     private String _subject; 
     private String _body; 

     private boolean _auth; 

     private boolean _debuggable; 

     private Multipart _multipart; 


   public Mail() { 
      _host = "smtp.gmail.com"; // default smtp server 
      _port = "465"; // default smtp port 
      _sport = "465"; // default socketfactory port 

      _user = ""; // username 
      _pass = ""; // password 
      _from = ""; // email sent from 
      _subject = ""; // email subject 
      _body = ""; // email body 

      _debuggable = false; // debug mode on or off - default off 
      _auth = true; // smtp authentication - default on 

      _multipart = new MimeMultipart(); 

      // There is something wrong with MailCap, javamail can not find a handler for the        multipart/mixed part, so this bit needs to be added. 
      MailcapCommandMap mc = (MailcapCommandMap) CommandMap.getDefaultCommandMap(); 
   mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html"); 
   mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml"); 
   mc.addMailcap("text/plain;; x-java-content-  handler=com.sun.mail.handlers.text_plain"); 
   mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed"); 
   mc.addMailcap("message/rfc822;; x-java-content- handler=com.sun.mail.handlers.message_rfc822"); 
    CommandMap.setDefaultCommandMap(mc); 
   } 

 public Mail(String user, String pass) { 
  this(); 

  _user = user; 
   _pass = pass; 
 } 

public boolean send() throws Exception { 
   Properties props = _setProperties(); 

  if(!_user.equals("") && !_pass.equals("") && _to.length > 0 && !_from.equals("") &&   !_subject.equals("") /*&& !_body.equals("")*/) { 
    Session session = Session.getInstance(props, this); 

    MimeMessage msg = new MimeMessage(session); 

     msg.setFrom(new InternetAddress(_from)); 

    InternetAddress[] addressTo = new InternetAddress[_to.length]; 
     for (int i = 0; i < _to.length; i++) { 
      addressTo[i] = new InternetAddress(_to[i]); 
    } 
      msg.setRecipients(MimeMessage.RecipientType.TO, addressTo); 

    msg.setSubject(_subject); 
    msg.setSentDate(new Date()); 

  // setup message body 
  BodyPart messageBodyPart = new MimeBodyPart(); 
    messageBodyPart.setText(_body); 
    _multipart.addBodyPart(messageBodyPart); 

     // Put parts in message 
    msg.setContent(_multipart); 

    // send email 
    Transport.send(msg); 

    return true; 
   } else { 
     return false; 
   } 
  } 

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

   _multipart.addBodyPart(messageBodyPart); 
 } 

  @Override 
  public PasswordAuthentication getPasswordAuthentication() { 
     return new PasswordAuthentication(_user, _pass); 
  } 

   private Properties _setProperties() { 
   Properties props = new Properties(); 

    props.put("mail.smtp.host", _host); 

  if(_debuggable) { 
    props.put("mail.debug", "true"); 
  } 

  if(_auth) { 
    props.put("mail.smtp.auth", "true"); 
   } 

    props.put("mail.smtp.port", _port); 
    props.put("mail.smtp.socketFactory.port", _sport); 
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
    props.put("mail.smtp.socketFactory.fallback", "false"); 

    return props; 
   } 

   // the getters and setters 
  public String getBody() { 
   return _body; 
 } 

 public void setBody(String _body) { 
  this._body = _body; 
 }

  public void setTo(String[] toArr) {
     // TODO Auto-generated method stub
    this._to=toArr;
 }

public void setFrom(String string) {
    // TODO Auto-generated method stub
    this._from=string;
}

 public void setSubject(String string) {
    // TODO Auto-generated method stub
    this._subject=string;
  }  


   }

첨부 파일을 추가하려면 추가하는 것을 잊지 마십시오.

MailcapCommandMap mc = (MailcapCommandMap) CommandMap
            .getDefaultCommandMap();
    mc.addMailcap("text/html;; x-java-content-handler=com.sun.mail.handlers.text_html");
    mc.addMailcap("text/xml;; x-java-content-handler=com.sun.mail.handlers.text_xml");
    mc.addMailcap("text/plain;; x-java-content-handler=com.sun.mail.handlers.text_plain");
    mc.addMailcap("multipart/*;; x-java-content-handler=com.sun.mail.handlers.multipart_mixed");
    mc.addMailcap("message/rfc822;; x-java-content-handler=com.sun.mail.handlers.message_rfc822");
    CommandMap.setDefaultCommandMap(mc);

참고 URL : https://stackoverflow.com/questions/2020088/sending-email-in-android-using-javamail-api-without-using-the-default-built-in-a

반응형