การส่งอีเมลใน Android โดยใช้ JavaMail API โดยไม่ต้องใช้แอปเริ่มต้น / ในตัว


653

ฉันกำลังพยายามสร้างแอปพลิเคชันส่งอีเมลใน Android

ถ้าฉันใช้:

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

นี่จะเป็นการเปิดแอปพลิเคชัน Android ในตัว ฉันกำลังพยายามส่งอีเมลบนปุ่มคลิกโดยตรงโดยไม่ต้องใช้แอปพลิเคชันนี้


3
javax.mail.AuthenticationFailedException เมื่อส่งอีเมลแม้ว่าผู้ใช้ / รหัสผ่านจะถูกต้อง ทางออกใด ๆ
TD Nguyen

1
โปรดทราบว่าในวันที่ 1.5.5 JavaMail อ้างว่าสนับสนุน Android
artbristol

1
ไม่ใช่SendGridตัวเลือกใช่ไหม เท่าที่ฉันรู้ว่าคุณยังมีโอกาสที่จะได้รับสถิติเกี่ยวกับ emai ที่คุณส่ง
Stamatis Stiliats

คำตอบ:


757

ส่งอีเมลใน Android โดยใช้ JavaMail API โดยใช้การตรวจสอบสิทธิ์ Gmail

ขั้นตอนในการสร้างตัวอย่างโครงการ:

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 ขวดเพิ่มในลิงก์ต่อไปนี้สำหรับโครงการ Android ของคุณ

คลิกที่นี่ - วิธีเพิ่มไหภายนอก

และอย่าลืมเพิ่มบรรทัดนี้ในรายการของคุณ:

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

เพียงคลิกลิงก์ด้านล่างเพื่อเปลี่ยนการเข้าถึงบัญชีสำหรับแอปที่ปลอดภัยน้อย https://www.google.com/settings/security/lesssecureapps

เรียกใช้โครงการและตรวจสอบบัญชีอีเมลของผู้รับเพื่อรับจดหมาย ไชโย!

PS และอย่าลืมว่าคุณไม่สามารถดำเนินการเครือข่ายจากกิจกรรมใด ๆ ใน Android ดังนั้นขอแนะนำให้ใช้AsyncTaskหรือIntentServiceเพื่อหลีกเลี่ยงเครือข่ายในข้อยกเว้นเธรดหลัก

ไฟล์ Jar: https://code.google.com/archive/p/javamail-android/


52
ดูเหมือนว่ารหัสของคุณจะใช้ชื่อผู้ใช้และรหัสผ่านที่กำหนดรหัสยาก ปัจจุบันนี้มีความเสี่ยงด้านความปลอดภัยหรือไม่ (หมายถึงมี apk ที่อัปโหลดไปยังตลาดถูกทำลายแล้ว) หรือไม่
รวย

11
ทำงานให้ฉัน !!! อย่าลืมที่จะเพิ่มลงในแอปของคุณอย่างชัดแจ้งถึงการอนุญาตให้ใช้อินเทอร์เน็ต
Avi Shukron

15
อย่างไรก็ตามมีวิธีรับอีเมลโดยไม่ใส่รหัสลงในรหัสหรือไม่ ฉันคิดว่าผู้ใช้จะต้องตกใจถ้าฉันจะถามพวกเขาสำหรับอีเมลของพวกเขา ...
pumpkee

7
สวัสดีขอบคุณสำหรับรหัส แต่ฉันได้ java.lang.NoClassDefFoundError บนผู้ส่ง GMailSender = GMailSender ใหม่ (... ) ใน mailsenderactivity ฉันรวมไหทั้งหมดและเพิ่มในการสร้างเส้นทาง ฉันใช้เวลาพอสมควรในการแก้ไข แต่ฉันไม่ได้รับการแก้ไข โปรดช่วยฉันด้วย
MAMurali

53
สำหรับผู้ที่บ่น / ถามเกี่ยวกับวิธีรับรหัสผ่านของผู้ใช้ - ไม่ใช่แนวคิดที่นี่ สิ่งนี้มีไว้เพื่อใช้กับบัญชีอีเมล (นักพัฒนา) ของคุณ หากคุณต้องการพึ่งพาบัญชีอีเมลของผู้ใช้คุณควรใช้เจตนาอีเมล์ซึ่งจะกล่าวถึงอย่างกว้างขวางในโพสต์อื่น ๆ
Tom

70

ขอบคุณสำหรับข้อมูลที่มีค่าของคุณ รหัสทำงานได้ดี ฉันสามารถเพิ่มไฟล์แนบได้ด้วยการเพิ่มรหัสต่อไปนี้

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
เพิ่มลงใน GmailSender.java
ขยะ

เมื่อฉันเรียก setcontent มันจะเขียนทับเนื้อหาร่างกายของฉัน ฉันกำลังทำอะไรผิด ฉันต้องการเพิ่มสิ่งที่แนบมากับเนื้อหาเนื้อหาแบบข้อความอื่น ๆ
Calvin

1
สำหรับfilenameตัวแปรที่นี่คุณต้องระบุพา ธ ของไฟล์ ตัวอย่างเช่น:String path = Environment.getExternalStorageDirectory().getPath() + "/temp_share.jpg";

รหัสนี้ช่วยให้คุณเพิ่มหลายไฟล์stackoverflow.com/a/3177640/2811343 ;) :)
AndroidManifester

54

ไม่สามารถเชื่อมต่อกับโฮสต์ SMTP: smtp.gmail.com, พอร์ต: 465

เพิ่มบรรทัดนี้ในรายการของคุณ:

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

39

คุณสามารถใช้ JavaMail API เพื่อจัดการงานอีเมลของคุณ JavaMail API พร้อมใช้งานในแพ็คเกจ JavaEE และสามารถดาวน์โหลด jar ได้ น่าเสียดายที่มันไม่สามารถใช้โดยตรงในแอปพลิเคชัน Android เนื่องจากใช้ส่วนประกอบ AWT ซึ่งเข้ากันไม่ได้อย่างสมบูรณ์ใน Android

คุณสามารถค้นหาพอร์ต Android สำหรับ JavaMail ได้ที่ตำแหน่งต่อไปนี้: http://code.google.com/p/javamail-android/

เพิ่มไหในแอปพลิเคชันของคุณและใช้วิธีการ SMTP


1
ที่เก็บ maven ใด ๆ
user1050755

ขออภัย แต่ฉันไม่ทราบว่า
Kshitij Aggarwal

6
ฉันได้ย้าย JavaMail ล่าสุดแล้วและมีอยู่ใน Maven Central ภายใต้eu.ocathain.com.sun.mail:javax.mail:1.5.2
artbristol

29

เพื่อช่วยให้ผู้ที่ได้รับข้อยกเว้นเธรดหลักบนเครือข่ายมีเป้าหมาย 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;
        }
    }

ตำแหน่งที่จะเพิ่มคลาสนี้
Gunaseelan

25

รหัสการทำงาน 100% พร้อมการสาธิตคุณสามารถส่งอีเมลหลายฉบับโดยใช้คำตอบนี้

ดาวน์โหลดโครงการที่นี่

ขั้นตอนที่ 1: ดาวน์โหลดเมลการเปิดใช้งานไฟล์ jar เพิ่มเติมและเพิ่มในโฟลเดอร์ libs โครงการของคุณใน android studio ฉันเพิ่มภาพหน้าจอดูที่ลิงค์ดาวน์โหลดด้านล่าง

libs เพิ่ม

เข้าสู่ระบบด้วย gmail ( ใช้จดหมายของคุณ ) และเปิด ปุ่มสลับลิงค์

คนส่วนใหญ่ลืมเกี่ยวกับขั้นตอนนี้ฉันหวังว่าคุณจะไม่

ขั้นตอนที่ 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"/>

หวังว่ามันจะทำงานถ้ามันไม่ได้แค่คอมเม้นท์ด้านล่าง


2
ปลอดภัยไหม หากฉันแทนที่ "fromEmail" และ "fromPassword" ด้วยชื่อผู้ใช้และรหัสผ่าน hardcoded ฉันต้องกังวลเกี่ยวกับปัญหาด้านความปลอดภัยหรือไม่
Yonah Karp

เป็นไปได้ไหมที่จะรับอีเมลโดยใช้วิธีการของคุณ? ฉันต้องการรับอีเมล
user3051460

1
@ArpitPatel มันใช้งานได้ค่อนข้างเรียบร้อย แต่ฉันก็ยังกังวลเกี่ยวกับความปลอดภัย หากคุณใช้ gmail Google อาจบล็อกแอปบางแอปที่พยายามทำเช่นนี้
Totumus Maximus

@TotumusMaximus หากคุณกังวลเกี่ยวกับความปลอดภัยมากกว่าที่คุณสามารถใช้อีเมลและรหัสผ่านของคุณโดยใช้ api
Arpit Patel

23

SMTP

การใช้ SMTP เป็นวิธีหนึ่งในการไปและคนอื่น ๆ ได้ชี้ให้เห็นวิธีการทำ เพียงแค่ทราบว่าในขณะที่ทำสิ่งนี้คุณจะหลีกเลี่ยงแอพอีเมลในตัวและคุณจะต้องระบุที่อยู่ของเซิร์ฟเวอร์ SMTP ชื่อผู้ใช้และรหัสผ่านสำหรับเซิร์ฟเวอร์นั้นทั้งในโค้ดของคุณหรือสอบถามจากผู้ใช้ .

HTTP

อีกวิธีหนึ่งจะเกี่ยวข้องกับสคริปต์ฝั่งเซิร์ฟเวอร์อย่างง่ายเช่น php ซึ่งใช้พารามิเตอร์ URL บางอย่างและใช้เพื่อส่งจดหมาย ด้วยวิธีนี้คุณเพียงแค่ทำการร้องขอ HTTP จากอุปกรณ์ (ทำได้ง่ายด้วยห้องสมุดในตัว) และไม่จำเป็นต้องจัดเก็บข้อมูลล็อกอินของ SMTP บนอุปกรณ์ นี่เป็นอีกหนึ่งทางอ้อมเมื่อเปรียบเทียบกับการใช้ SMTP โดยตรง แต่เนื่องจากง่ายต่อการร้องขอ HTTP และส่งอีเมลจาก PHP จึงอาจทำได้ง่ายกว่าวิธีโดยตรง

แอปพลิเคชันจดหมาย

หากเมลนั้นจะถูกส่งจากบัญชีเมลเริ่มต้นของผู้ใช้ที่เขาลงทะเบียนไว้กับโทรศัพท์แล้วคุณจะต้องใช้วิธีอื่น หากคุณมีเวลาและประสบการณ์เพียงพอคุณอาจต้องการตรวจสอบซอร์สโค้ดของแอปพลิเคชันอีเมล Android เพื่อดูว่ามีจุดเข้าใช้งานเพื่อส่งอีเมลโดยไม่มีการโต้ตอบกับผู้ใช้หรือไม่ (ฉันไม่รู้ แต่อาจมีอยู่)

บางทีคุณอาจจะค้นหาวิธีสอบถามรายละเอียดบัญชีผู้ใช้ (เพื่อให้คุณสามารถใช้พวกเขาสำหรับ SMTP) แต่ฉันสงสัยอย่างมากว่ามันเป็นไปได้เพราะมันอาจเป็นความเสี่ยงด้านความปลอดภัยขนาดใหญ่และ Android นั้นค่อนข้างปลอดภัย


22

นี่คือเวอร์ชัน alt ที่ใช้งานได้สำหรับฉันและมีไฟล์แนบ (โพสต์ไว้ด้านบนแล้ว แต่เวอร์ชันสมบูรณ์เหมือนลิงค์แหล่งที่มาซึ่งผู้คนโพสต์ไม่สามารถใช้งานได้เนื่องจากข้อมูลที่ขาดหายไป)

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

@KeyLimePiePhotonAndroid เพิ่มการอนุญาตทางอินเทอร์เน็ตให้กับรายการของคุณ
noob

จะใช้รหัสนี้อย่างไรหากฉันต้องการใช้โปรแกรมรับส่งเมลอื่นเช่น org ของฉัน การเปลี่ยนชื่อโฮสต์และพอร์ตจะเพียงพอหรือไม่
roger_that

javax.mail.AuthenticationFailed ยกเว้นวิธีแก้ปัญหาสำหรับ android 4.4.4?
TD Nguyen

2
สำหรับ javax.mail.AuthenticationFailedException คุณต้องเปิดการตั้งค่านี้google.com/settings/security/lesssecureapps
Razel Soco

1
เพื่อแก้Could not send email android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetworkมันเป็นสิ่งจำเป็นที่จะเห็นการแก้ปัญหานี้stackoverflow.com/questions/25093546/...
jgrocha

14

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

แหล่ง

(ฉันได้ทดสอบด้วยตัวเอง)


ฉันใช้มันและทำงานได้อย่างสมบูรณ์แบบ แต่ฉันได้ทำการดัดแปลงบางอย่างเพื่อใช้กับผู้ให้บริการอีเมลที่แตกต่างกันและเมื่อส่งอีเมลไปยัง Gmail มันจะส่งคืนส่วนหัว "จาก" หายไป ... แก้ปัญหาได้อย่างไร
Erich García

สวัสดีฉันใช้ api นี้ในแอปของฉัน แต่มันใช้งานไม่ได้และโทรหา onfailcallback เสมอ
Jawad Malik

13

คำเตือนถ้าใช้ "smtp.gmail.com" เป็นเซิร์ฟเวอร์ smtp เริ่มต้น

Google จะบังคับให้คุณเปลี่ยนรหัสผ่านบัญชีอีเมลที่เชื่อมโยงของคุณเป็นประจำเนื่องจากนโยบาย "กิจกรรมที่น่าสงสัย" ของพวกเขาอย่างกระตือรือร้น ในสาระสำคัญจะถือว่าคำขอ smtp ซ้ำจากประเทศต่าง ๆ ภายในระยะเวลาอันสั้นเป็น "กิจกรรมที่น่าสงสัย" เนื่องจากพวกเขาถือว่าคุณ (เจ้าของบัญชีอีเมล) สามารถอยู่ในประเทศเดียวในแต่ละครั้ง

เมื่อระบบ google ตรวจพบ "กิจกรรมที่น่าสงสัย" ระบบจะป้องกันอีเมลเพิ่มเติมจนกว่าคุณจะเปลี่ยนรหัสผ่าน เนื่องจากคุณจะได้ใส่รหัสผ่านลงในแอพอย่างหนักคุณต้องรีลีสแอปใหม่ทุกครั้งที่เกิดเหตุการณ์นี้ขึ้น สิ่งนี้เกิดขึ้น 3 ครั้งต่อสัปดาห์สำหรับฉันฉันยังเก็บรหัสผ่านไว้ในเซิร์ฟเวอร์อื่นและดึงรหัสผ่านแบบไดนามิกทุกครั้งที่ Google บังคับให้ฉันเปลี่ยน

ดังนั้นฉันขอแนะนำให้ใช้หนึ่งในผู้ให้บริการ smtp ฟรีจำนวนมากแทนที่จะเป็น "smtp.gmail.com" เพื่อหลีกเลี่ยงปัญหาความปลอดภัยนี้ ใช้รหัสเดียวกัน แต่เปลี่ยน "smtp.gmail.com" เป็นโฮสต์การส่งต่อ smtp ใหม่ของคุณ


2
นั่นเป็นจุดที่ดี แต่คุณสามารถโปรดยกตัวอย่างผู้ให้บริการอีเมลสำรองที่ทำงานกับรหัสได้ (แทนที่รายละเอียด smtp และเข้าสู่ระบบเท่านั้น) ฉันได้ลองกับ hushmail และ email.com แล้ว แต่ไม่ประสบความสำเร็จ จะพยายามต่อไปกับคนอื่น
เปาโล Matuki

@ PauloMatuki @ Mark สวัสดีพวกคุณช่วยแก้suspicioud activityปัญหาได้มั้ย
Wesley

7

แก้ไข: 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


บรรทัด Maven / Gradle นั้นใช้ไม่ได้สำหรับฉัน การดาวน์โหลด 1.5.4 จาก bitbucket ของคุณก็ไม่ได้ผลสำหรับฉัน มันล้มเหลวในบรรทัดเดียวกับ javamail ที่ไม่ใช่ Android ปกติซึ่งเป็น MimeMessage.setText (ข้อความ)
wrapperapps

@wrapperapps เสียใจที่ได้ยินเช่นนั้น "มันใช้งานได้สำหรับฉัน!" อย่าลังเลที่จะเปิดปัญหาใน repo
bitbucket

7

ฉันพบทางเลือกที่สั้นกว่าสำหรับผู้อื่นที่ต้องการความช่วยเหลือ รหัสคือ:

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

หวังว่านี่จะช่วยได้! โชคดี!


5

ผู้ที่ClassDefNotFoundErrorพยายามย้ายไฟล์ Three jar ไปยังโฟลเดอร์ lib ของโปรเจคของคุณมันใช้งานได้สำหรับฉัน !!


4

สำหรับการส่งเมลพร้อมไฟล์แนบ ..

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

เพิ่มการเปิดใช้งาน jar ไฟล์ jar, นอกจากนี้.jar, javax.mail.jar
Rashid

1
ฉันได้รับข้อผิดพลาดต่อไปนี้เมื่อลองใช้วิธีการของคุณ: 05-13 11: 51: 50.454: E / AndroidRuntime (4273): android.os.NetworkOnMainThreadException 05-13 11: 51: 50.454: E / AndroidRuntime (4273): ที่ android os.StrictMode $ AndroidBlockGuardPolicy.onNetwork (StrictMode.java:1156) ฉันมีสิทธิ์อินเทอร์เน็ต คำแนะนำใด ๆ?
kodartcha

1
ลองเรียกวิธีการในเธรด ... มันเป็นกระบวนการที่ใช้เวลานาน ... มันไม่สามารถรันบนเธรดหลัก ...
Rashid

กำลังใช้รหัสนี้อย่างแน่นอนในโครงการ Android ของฉันจดหมายทำงานได้ดีสำหรับฉัน แต่ส่วนที่แนบมาไม่ทำงาน กำลังพยายามแนบไฟล์. txt แต่เมลที่ได้รับประกอบด้วยไฟล์ประเภทที่ไม่รู้จักซึ่งไม่สามารถเปิดได้ กรุณาช่วย.
Syamantak Basu

@Rashid ofcourse ฉันทำอย่างนั้น เมื่อก่อนหน้านี้ฉันใช้ Intent ไฟล์ที่แนบมาของฉันกำลังจะมา
Syamantak Basu

4

ฉันไม่สามารถเรียกใช้รหัสของ Vinayak B ได้ ในที่สุดฉันก็แก้ไขปัญหานี้ได้โดยทำตาม:

1. การใช้สิ่งนี้

2. ใช้ AsyncTask

3. การเปลี่ยนปัญหาด้านความปลอดภัยของบัญชีผู้ส่ง gmail (เปลี่ยนเป็น "เปิด") ในเรื่องนี้


3

คุณพิจารณาใช้ Apache Commons Net หรือไม่ ตั้งแต่ 3.3 เพียงหนึ่งขวด (และคุณสามารถพึ่งพาได้โดยใช้ gradle หรือ Maven) และคุณทำเสร็จแล้ว: http://blog.dahanne.net/2013/06/17/sending-a-mail-in-java- และหุ่นยนต์ที่มี Apache-คอมมอนสุทธิ /


3

คุณสามารถส่งดังนี้:

  1. ส่งอีเมลจากลูกค้า apk นี่ mail.jar, activation.jar จะต้องส่งอีเมล java หากมีการเพิ่มไหเหล่านี้อาจเพิ่มขนาด APK

  2. หรือคุณสามารถใช้บริการเว็บที่รหัสฝั่งเซิร์ฟเวอร์ซึ่งจะใช้ mail.jar และ activation.jar เดียวกันเพื่อส่งอีเมล คุณสามารถโทรหาบริการเว็บผ่าน asynctask และส่งอีเมล อ้างอิงลิงค์เดียวกัน

(แต่คุณจะต้องรู้ข้อมูลประจำตัวของบัญชีอีเมล)


2

ในกรณีที่คุณต้องการให้ไลบรารี jar มีขนาดเล็กที่สุดเท่าที่จะเป็นไปได้คุณสามารถรวมฟังก์ชั่น SMTP / POP3 / IMAP แยกต่างหากเพื่อหลีกเลี่ยงปัญหา "วิธีการมากเกินไปใน dex"

คุณสามารถเลือก jar jar ที่ต้องการได้จากเว็บเพจ javanetตัวอย่างเช่น mailapi.jar + imap.jar สามารถให้คุณเข้าถึง icloud, hotmail mail server ในโปรโตคอล IMAP (ด้วยความช่วยเหลือของ extra.jar และ activation.jar)


2

ฉันลองใช้รหัสที่ @Vinayak B ส่งมา อย่างไรก็ตามฉันได้รับข้อผิดพลาดที่บอกว่า: ไม่มีผู้ให้บริการสำหรับ smtp

ฉันสร้างคำถามใหม่สำหรับสิ่งนี้พร้อมข้อมูลเพิ่มเติมที่นี่

ฉันสามารถแก้ไขได้ด้วยตนเอง ฉันต้องใช้mail.jarอื่น และต้องตรวจสอบให้แน่ใจว่าได้เปิด " การเข้าถึงแอพที่ปลอดภัยน้อยกว่า "

ฉันหวังว่านี่จะช่วยให้ทุกคนที่มีปัญหาเดียวกัน เมื่อทำสิ่งนี้เสร็จแล้วโค้ดชิ้นนี้ก็สามารถใช้งานได้บน google แก้วด้วย


2

ทุกรหัสที่ให้ไว้ในคำตอบอื่น ๆ ถูกต้องและทำงานได้ดี แต่ยุ่งบิตดังนั้นผมจึงตัดสินใจที่จะเผยแพร่ห้องสมุด (ยังคงอยู่ในการพัฒนาแม้ว่า) ที่จะใช้มันในทางที่ง่ายขึ้น: 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);

คุณสามารถรับการแจ้งเตือนสำหรับอีเมลที่ส่งและมีการสนับสนุนประเภทผู้รับที่แตกต่างกัน (TO, CC และ BCC), ไฟล์แนบและ 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'

โปรดแจ้งให้เราทราบหากคุณมีปัญหาใด ๆ กับมัน! :)


1

นี่คือโซลูชั่นมากมาย อย่างไรก็ตามฉันคิดว่าเราต้องเปลี่ยนการกำหนดค่า GMail เพื่อให้สามารถเข้าถึงได้จากอุปกรณ์ที่มีความปลอดภัยน้อยกว่า ไปที่ลิงก์ด้านล่างและเปิดใช้งาน มันใช้งานได้สำหรับฉัน

https://myaccount.google.com/lesssecureapps?pli=1


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


   }

0

ส่งอีเมลแบบเป็นโปรแกรมด้วย Kotlin

  • การส่งอีเมลอย่างง่ายไม่ใช่คุณสมบัติอื่น ๆ ทั้งหมด (เช่นไฟล์แนบ)
  • TLS เปิดอยู่เสมอ
  • จำเป็นต้องมีการพึ่งพาอีเมล gradle เพียง 1 รายการเท่านั้น

ฉันพบว่าบริการอีเมล POP นี้มีประโยชน์จริง ๆ :

https://support.office.com/en-gb/article/pop-and-imap-email-settings-for-outlook-8361e398-8af4-4e97-b147-6c6c4ac95353

วิธีใช้:

    val auth = EmailService.UserPassAuthenticator("you@gmail.com", "yourPassword")
    val to = listOf(InternetAddress("to@email.com"))
    val from = InternetAddress("you@gmail.com")
    val email = EmailService.Email(auth, to, from, "Test Subject", "Hello Body World")
    val emailService = EmailService("smtp.gmail.com", 465)

    GlobalScope.launch { // or however you do background threads
        emailService.send(email)
    }

รหัส:

import java.util.*
import javax.mail.*
import javax.mail.internet.InternetAddress
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMessage
import javax.mail.internet.MimeMultipart

class EmailService(private val server: String, private val port: Int) {

    data class Email(
        val auth: Authenticator,
        val toList: List<InternetAddress>,
        val from: Address,
        val subject: String,
        val body: String
    )

    class UserPassAuthenticator(private val username: String, private val password: String) : Authenticator() {
        override fun getPasswordAuthentication(): PasswordAuthentication {
            return PasswordAuthentication(username, password)
        }
    }

    fun send(email: Email) {
        val props = Properties()
        props["mail.smtp.auth"] = "true"
        props["mail.user"] = email.from
        props["mail.smtp.host"] = server
        props["mail.smtp.port"] = port
        props["mail.smtp.starttls.enable"] = "true"
        props["mail.smtp.ssl.trust"] = server
        props["mail.mime.charset"] = "UTF-8"
        val msg: Message = MimeMessage(Session.getDefaultInstance(props, email.auth))
        msg.setFrom(email.from)
        msg.sentDate = Calendar.getInstance().time
        msg.setRecipients(Message.RecipientType.TO, email.toList.toTypedArray())
//      msg.setRecipients(Message.RecipientType.CC, email.ccList.toTypedArray())
//      msg.setRecipients(Message.RecipientType.BCC, email.bccList.toTypedArray())
        msg.replyTo = arrayOf(email.from)

        msg.addHeader("X-Mailer", CLIENT_NAME)
        msg.addHeader("Precedence", "bulk")
        msg.subject = email.subject

        msg.setContent(MimeMultipart().apply {
            addBodyPart(MimeBodyPart().apply {
                setText(email.body, "iso-8859-1")
                //setContent(email.htmlBody, "text/html; charset=UTF-8")
            })
        })
        Transport.send(msg)
    }

    companion object {
        const val CLIENT_NAME = "Android StackOverflow programmatic email"
    }
}

Gradle:

dependencies {
    implementation 'com.sun.mail:android-mail:1.6.4'
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3"
}

AndroidManifest:

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

-3

หากต้องการเพิ่มไฟล์แนบอย่าลืมเพิ่ม

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);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.