在服务中发送电子邮件(无需提示用户)

5

我是否可以使用服务在后台发送电子邮件?例如,在服务中使用ACTION_SENDTO意图和URI数据mailto:recipient_email,它可以在后台发送而不需要任何用户干预。或者通过默认的电子邮件应用程序而不提示用户...


你想要通过编程方式发送电子邮件吗? - Muhammad Zeeshan
是的,但要使用用户配置的电子邮件而不是其他电子邮件。 - Waheed Khan
1
请查看以下这些解决方案:https://dev59.com/VW855IYBdhLWcg3wbzxl 和 http://stackoverflow.com/questions/5456688/how-to-send-email-from-an-android-application。 - Muhammad Zeeshan
1个回答

5

最佳解决方案是使用Gmail帐户发送电子邮件。

一般来说:

  1. 下载android的mail.jar和activation.jar:https://code.google.com/p/javamail-android/
  2. 连接到Gmail获取OAuth令牌
  3. 发送电子邮件

以下是代码:

import java.util.Properties;

import javax.activation.DataHandler;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.URLName;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;

import com.sun.mail.smtp.SMTPTransport;
import com.sun.mail.util.BASE64EncoderStream;

public class GMailSender {
    private Session session;
    private String token;


    public String getToken() {
        return token;
    }

    public GMailSender(Activity ctx) {
        super();
        initToken(ctx);
    }

    public void initToken(Activity ctx) {

        AccountManager am = AccountManager.get(ctx);

        Account[] accounts = am.getAccountsByType("com.google");
        for (Account account : accounts) {
            Log.d("getToken", "account="+account);  
        }

        Account me = accounts[0]; //You need to get a google account on the device, it changes if you have more than one


        am.getAuthToken(me, "oauth2:https://mail.google.com/", null, ctx, new AccountManagerCallback<Bundle>(){
            @Override
            public void run(AccountManagerFuture<Bundle> result){
                try{
                    Bundle bundle = result.getResult();
                    token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
                    Log.d("initToken callback", "token="+token);    

                } catch (Exception e){
                    Log.d("test", e.getMessage());
                }
            }
        }, null);

        Log.d("getToken", "token="+token);
    }



    public SMTPTransport connectToSmtp(String host, int port, String userEmail,
            String oauthToken, boolean debug) throws Exception {

        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.sasl.enable", "false");

        session = Session.getInstance(props);
        session.setDebug(debug);

        final URLName unusedUrlName = null;
        SMTPTransport transport = new SMTPTransport(session, unusedUrlName);
        // If the password is non-null, SMTP tries to do AUTH LOGIN.
        final String emptyPassword = null;

        /* enable if you use this code on an Activity (just for test) or use the AsyncTask
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
         */

        transport.connect(host, port, userEmail, emptyPassword);

        byte[] response = String.format("user=%s\1auth=Bearer %s\1\1",
                userEmail, oauthToken).getBytes();
        response = BASE64EncoderStream.encode(response);

        transport.issueCommand("AUTH XOAUTH2 " + new String(response), 235);

        return transport;
    }

    public synchronized void sendMail(String subject, String body, String user,
            String oauthToken, String recipients) {
        try {

            SMTPTransport smtpTransport = connectToSmtp("smtp.gmail.com", 587,
                    user, oauthToken, true);

            MimeMessage message = new MimeMessage(session);
            DataHandler handler = new DataHandler(new ByteArrayDataSource(
                    body.getBytes(), "text/plain"));
            message.setSender(new InternetAddress(user));
            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));
            smtpTransport.sendMessage(message, message.getAllRecipients());

        } catch (Exception e) {
            Log.d("test", e.getMessage(), e);
        }
    }

}

这段代码最初发布于使用XOauth实现Javamail API在Android上的应用

请注意,为了获取OAuth令牌,您需要一个Activity并要求用户选择要使用的帐户。应在OnCreate阶段检索令牌并将其保存在首选项中。另请参见如何获取Android设备的主电子邮件地址

或者,您可以使用mail.jar,但必须要求用户提供他们的用户名和密码。


2
您也可以从服务中获取oauth令牌,使用公共的AccountManagerFuture<Bundle> getAuthToken(Account account, String authTokenType, Bundle options, boolean notifyAuthFailure, AccountManagerCallback<Bundle> callback, Handler handler)方法。http://developer.android.com/reference/android/accounts/AccountManager.html - alex
你能告诉我在哪里获取这个完整的功能吗?我已经创建了GmailSender类并集成了Google登录,但我无法在后台发送邮件。 - Savita Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接