[java] 기본 / 내장 앱을 사용하지 않고 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;
            }
        });
    }
}

Android 프로젝트에 대한 다음 링크에서 3 개의 항아리 추가

여기를 클릭하십시오-외부 병을 추가하는 방법

그리고이 줄을 매니페스트에 추가하는 것을 잊지 마십시오.

<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/

항아리를 응용 프로그램에 추가하고 SMTP 방법을 사용하십시오.


답변

SDK 대상이> 9 인 네트워크에서 메인 스레드 예외가 발생하는 것을 돕기 위해. 이것은 위의 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;
        }
    }


답변

데모를 사용한 100 % 작업 코드이 답변을 사용하여 여러 개의 이메일을 보낼 수도 있습니다.

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

1 단계 : 메일, 활성화, 추가 jar 파일을 다운로드 하고 android studio 의 프로젝트 라이브러리 폴더 에 추가하십시오 . 스크린 샷을 추가했습니다. 아래 링크를 참조하십시오.

라이브러리 추가

Gmail로 로그인 ( 메일에서 사용 ) 및 켜기 토글 버튼 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"/>

그것이 아래에 주석을 달지 않으면 효과가 있기를 바랍니다.


답변

SMTP

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

HTTP

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

메일 신청

이미 전화로 등록한 사용자 기본 메일 계정에서 메일을 보내려면 다른 방법을 사용해야합니다. 시간과 경험이 충분하면 Android 전자 메일 응용 프로그램의 소스 코드를 확인하여 사용자 상호 작용없이 메일을 보낼 수있는 진입 점이 있는지 확인할 수 있습니다 (모르지만 모르겠습니다).

어쩌면 사용자 계정 세부 정보를 쿼리하는 방법을 찾을 수도 있습니다 (SMTP에 사용할 수 있음). 큰 보안 위험이 있으며 Android가 다소 안전하게 구축되어 있기 때문에 이것이 가능할 것입니다.