`
melord
  • 浏览: 145849 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Android平台邮件自动发送功能实现

 
阅读更多

Android 自动发送邮件

本文简述的是在Android平台如何自动发送邮件(没有邮件编写界面),主要应用场景为忘记密码等安全等级较高的操作,比如我忘记密码了,点击“发送密码到我的邮箱”系统会将密码发送到注册时的电子邮件地址。

 

Android平台邮件客户端

Gmail: Gmai电子邮件客户端

Email: 通用的电子邮件客户端

 

解决方案

Gmail

Gmail已经支持自动发送了,所以非常简单。在使用时,需要添加

<uses-permission android:name="com.google.android.gm.permission.AUTO_SEND" /> 到AndroidManifest.xml

示例代码如下:

		 Intent intent = new Intent("com.google.android.gm.action.AUTO_SEND");
		 intent.setType("plain/text");
		 String[] reciver = new String[] { "xxxx@xxx.com" };
		 String subject = "email title";
		 String body = "email body";
		 intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver);
		 intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
		 intent.putExtra(android.content.Intent.EXTRA_TEXT, body);

 Email

Email不支持自动发送,但又是默认邮件客户端,所以需要添加自动发送功能。主要实现步骤为:

编写一个自动发送邮件类

主要功能为:接收用户输入,组装message对象,获取Sender实例,将message发送出去,最后删除message对象(这样已发送的邮件内容不会出现在client中,提高发安全性)

package com.android.email.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.net.Uri;
import android.widget.Toast;

import com.android.emailcommon.provider.EmailContent;
import com.android.emailcommon.provider.EmailContent.Account;
import com.android.emailcommon.provider.EmailContent.Message;
import com.android.emailcommon.mail.MessagingException;
import com.android.emailcommon.mail.Address;
import com.android.emailcommon.utility.Utility;
import com.android.emailcommon.mail.AuthenticationFailedException;
import com.android.email.EmailAddressValidator;
import com.android.email.mail.Sender;

/**
 * Send email in background with account configured in Email application.
 * Sending message will not saved as draft or in out-going box. Usage:
 * 
 * <pre>
 * Intent intent = new Intent(&quot;com.android.email.intent.action.sendInBack&quot;);
 * String[] reciver = new String[] { &quot;your_name@corp.com&quot; };
 * String subject = &quot;email title&quot;;
 * String body = &quot;email body &quot;;
 * intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]);
 * intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
 * intent.putExtra(android.content.Intent.EXTRA_TEXT, body);
 * startActivityForResult(Intent.createChooser(intent, &quot;send&quot;), 0x02);
 * </pre>
 * 
 * Now, attachment and multi-receiver function is unsupported.
 * 
 * @author melord
 * 
 */
public class EmailSendAutoActivity extends Activity implements SendListener {

    private static String tag = "EmailSendAutoAcitivity";
    private Context mContext;

    private String mTo;
    private String mCc;
    private String mBcc;
    private String mSubject;
    private String mBody;

    private EmailAddressValidator mValidator = new EmailAddressValidator();
    private SendListener mListener;
    private Toast mWaiting;
    private boolean enableLog = true;

    /**
     * Sending account email address.
     */
    private String mSendEmail;
    /**
     * Sending account id
     */
    private long mAccountId = -1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.mContext = this;
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        mListener = this;
        Intent intent = getIntent();
        initMessageFromIntent(intent);
        initAccountFromIntent(intent);

        new SendTask().execute();
        String msg = intent.getStringExtra("sendMsg");
        if (msg == null) {
            msg = "Sending message...";
        }
        // mWaiting = ProgressDialog.show(this, "", "sending...", true, true,
        // null);
        mWaiting = Toast.makeText(this, msg, Toast.LENGTH_LONG);
        mWaiting.show();
    }

    @Override
    public void onBackPressed() {
        if (mWaiting != null) {
            mWaiting.cancel();
        }
        super.onBackPressed();
    }

    @Override
    public void finish() {
        if (mWaiting != null) {
            mWaiting.cancel();
        }
        super.finish();
    }

    /**
     * Initialize sending account from intent.
     * 
     * @param intent
     *            imcoming intent
     */
    private void initAccountFromIntent(Intent intent) {
        String email = intent.getStringExtra("sendAccount");
        if (email != null) {
            log(String.format("send email use account (%s) ", email));
            mSendEmail = email;
            Long[] ids = EmailContent.Account.getAllAccountIds(this);
            if (ids != null && ids.length > 0) {
                for (int i = 0; i < ids.length; i++) {
                    EmailContent.Account temp = EmailContent.Account
                            .restoreAccountWithId(this, ids[i]);
                    if (temp != null && email.equals(temp.getEmailAddress())) {
                        log("valid account");
                        mAccountId = ids[i];
                        break;
                    }
                }
            }
        }
    }

    /**
     * Initialize message from intent.
     * 
     * @param intent
     *            intent
     */
    private void initMessageFromIntent(Intent intent) {
        String to = intent.getStringExtra(Intent.EXTRA_EMAIL);
        mTo = composeAddress(to);

        String cc = intent.getStringExtra(Intent.EXTRA_CC);
        mCc = composeAddress(cc);

        String bcc = intent.getStringExtra(Intent.EXTRA_BCC);
        mBcc = composeAddress(bcc);

        mSubject = intent.getStringExtra(Intent.EXTRA_SUBJECT);

        mBody = intent.getStringExtra(Intent.EXTRA_TEXT);

        log("to:" + mTo);
        log("cc:" + mCc);
        log("bcc:" + mBcc);

    }

    /**
     * change to stand email address reference to Rfc822
     * 
     * @param address
     *            email address
     * @return RFC822 format email address
     */
    private String composeAddress(String address) {
        String addr = null;
        if (!TextUtils.isEmpty(address)) {
            Address[] addresses = Address.parse(address.trim());
            addr = Address.pack(addresses);
        }
        return addr;
    }

    /**
     * Update message. fill fields.
     * 
     * @param message
     *            email message
     * @param account
     *            sending account
     */
    private void updateMessage(Message message, Account account) {
        if (message.mMessageId == null || message.mMessageId.length() == 0) {
            message.mMessageId = Utility.generateMessageId();
        }
        message.mTimeStamp = System.currentTimeMillis();
        // it will : Name<Address>
        message.mFrom = new Address(account.getEmailAddress(), account
                .getSenderName()).pack();
        message.mTo = mTo;
        message.mCc = mCc;
        message.mBcc = mBcc;
        message.mSubject = mSubject;
        message.mText = mBody;
        message.mAccountKey = account.mId;
        // here just used account setting simply
        message.mDisplayName = account.getSenderName();
        message.mFlagRead = true;
        message.mFlagLoaded = Message.FLAG_LOADED_COMPLETE;

    }

    private void log(String msg) {
        if (enableLog) {
            Log.i(tag, msg);
        }
    }

    /**
     * Really send message.
     * 
     * @param account
     *            sending account
     * @param messageId
     *            message id
     */
    public void sendMessage(Account account, long messageId) {
        // message uri
        Uri uri = ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI,
                messageId);
        try {
            // get a sender, ex. smtp sender.
            Sender sender = Sender.getInstance(mContext, account
                    .getSenderUri(mContext));
            // sending started
            mListener.onStarted(account.mId, messageId);
            // sending
            sender.sendMessage(messageId);
            // send completed
            mListener.onCompleted(account.mId);

        } catch (MessagingException me) {
            // report error
            mListener.onFailed(account.mId, messageId, me);
        } finally {
            try {
                // delete this message whenever send successfully or not
                mContext.getContentResolver().delete(uri, null, null);
            } catch (Exception ex) {
                Log.w(tag, "delete message occur exception message uri:" + uri);
            }
        }
    }

    public void onCompleted(long accountId) {
        log("send mail ok");
        // return Activity.RESULT_OK when send successfully
        setResult(RESULT_OK);
        finish();
    }

    public void onFailed(long accountId, long messageId, Exception ex) {
        log("send mail failed : " + ex.toString());
        finish();
    }

    public void onStarted(long messageId, long accountId) {
        log("send mail started");
    }

    /**
     * Send message task, it is an async task
     * 
     * @author melord_li
     * 
     */
    private class SendTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            // get default account, if not set, first record is treated as
            // default.
            // long id = Account.getDefaultAccountId(mContext);
            long id = mAccountId;
            if (id < 0) {
                id = Account.getDefaultAccountId(mContext);
            }
            if (id < 0) {
                Log.w(tag, "no account exists");
                finish();
                return null;
            }
            // get full account message
            Account account = Account.restoreAccountWithId(mContext, id);

            // A empty message
            Message message = new Message();
            // fill message field
            updateMessage(message, account);

            // Save this message. Because send API will read message in message
            // db.
            Uri uri = message.save(mContext);
            if (uri == null) {
                Log.e(tag, "save message occured an error");
                finish();
                return null;
            }

            // send
            sendMessage(account, message.mId);
            return null;
        }
    }
}

/**
 * Sending monitor
 * 
 * @author melord
 * 
 */
interface SendListener {

    /**
     * Send failed.
     * 
     * @param accountId
     *            account id
     * @param messageId
     *            message id
     * @param ex
     *            exception
     */
    void onFailed(long accountId, long messageId, Exception ex);

    /**
     * Send begin.
     * 
     * @param accountId
     *            account id
     * @param messageId
     *            message id
     */
    void onStarted(long messageId, long accountId);

    /**
     * Send completed.
     * 
     * @param accountId
     *            account id
     */
    void onCompleted(long accountId);
}

 配置

        <activity android:name=".activity.EmailSendAutoActivity" android:theme="@android:style/Theme.Translucent">
            <intent-filter>
                <action android:name="com.android.email.intent.action.sendInBack"/>
                <data android:mimeType="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

 使用

		Intent intent = new Intent("com.android.email.intent.action.sendInBack");
		String[] reciver = new String[] { "yourname@corp.com" };
		String subject = "email title";
		String body = "email body";
		intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver[0]);
		intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
		intent.putExtra(android.content.Intent.EXTRA_TEXT, body);

		startActivityForResult(Intent.createChooser(intent, "send"), 0x02);

 处理回调

如果发送成功,会返回RESULT_OK。

 

分享到:
评论
7 楼 chin1361 2012-09-06  
melord 写道
chin1361 写道
melord 写道
chin1361 写道
楼主,我用了第一种方法和1楼一样的结果。 想问下调用这个com.google.android.gm.permission.AUTO_SEND权限有没有什么条件?比如版本,需要导入包等。

版本为3.0及其以上. 需要装Gmail.apk.

我换成4.0.3版本,且gmail为4.1.2了还是没成功。这个自定义的权限类在什么位置?是不是我还没下载下来,android——sdk中很多资料无法下载。

如果这样子的话,你反编译一下GMail.apk吧,在AndroidManifest.xml中。

能把你的联系方式给下么QQ或MSN,我把我的代码发给你。能帮我看看么?
gmail apk反编译出来的文件为空。但有在里面有看到autosendactivity.clss这个文件。
6 楼 melord 2012-09-06  
chin1361 写道
melord 写道
chin1361 写道
楼主,我用了第一种方法和1楼一样的结果。 想问下调用这个com.google.android.gm.permission.AUTO_SEND权限有没有什么条件?比如版本,需要导入包等。

版本为3.0及其以上. 需要装Gmail.apk.

我换成4.0.3版本,且gmail为4.1.2了还是没成功。这个自定义的权限类在什么位置?是不是我还没下载下来,android——sdk中很多资料无法下载。

如果这样子的话,你反编译一下GMail.apk吧,在AndroidManifest.xml中。
5 楼 chin1361 2012-09-05  
melord 写道
chin1361 写道
楼主,我用了第一种方法和1楼一样的结果。 想问下调用这个com.google.android.gm.permission.AUTO_SEND权限有没有什么条件?比如版本,需要导入包等。

版本为3.0及其以上. 需要装Gmail.apk.

我换成4.0.3版本,且gmail为4.1.2了还是没成功。这个自定义的权限类在什么位置?是不是我还没下载下来,android——sdk中很多资料无法下载。
4 楼 melord 2012-08-16  
chin1361 写道
楼主,我用了第一种方法和1楼一样的结果。 想问下调用这个com.google.android.gm.permission.AUTO_SEND权限有没有什么条件?比如版本,需要导入包等。

版本为3.0及其以上. 需要装Gmail.apk.
3 楼 chin1361 2012-08-10  
楼主,我用了第一种方法和1楼一样的结果。 想问下调用这个com.google.android.gm.permission.AUTO_SEND权限有没有什么条件?比如版本,需要导入包等。
2 楼 melord 2012-05-29  
Jasper_Success 写道
楼主,我试了第一种方法,怎么不行啊,在模拟器上和真机上都不行
真机上报

05-10 09:06:38.880: ERROR/AndroidRuntime(2972): java.lang.SecurityException: Permission Denial:
starting Intent { act=com.google.android.gm.action.AUTO_SEND typ=plain/text cmp=com.google.android.gm/.AutoSendActivity (has extras) } from ProcessRecord{47a829b0 2972:com.eagleguard.www.activity/10136} (pid=2972, uid=10136) requires com.google.android.gm.permission.AUTO_SEND

很明显,权限并没有加上去,你试着重新编译一下整个工程吧.
1 楼 Jasper_Success 2012-05-10  
楼主,我试了第一种方法,怎么不行啊,在模拟器上和真机上都不行
真机上报

05-10 09:06:38.880: ERROR/AndroidRuntime(2972): java.lang.SecurityException: Permission Denial:
starting Intent { act=com.google.android.gm.action.AUTO_SEND typ=plain/text cmp=com.google.android.gm/.AutoSendActivity (has extras) } from ProcessRecord{47a829b0 2972:com.eagleguard.www.activity/10136} (pid=2972, uid=10136) requires com.google.android.gm.permission.AUTO_SEND

我在manifest.xml中已经加了
<uses-permission android:name="com.google.android.gm.permission.AUTO_SEND" />
这是我源码
Intent intent = new Intent("com.google.android.gm.action.AUTO_SEND");  
				intent.setType("plain/text");  
				String[] reciver = new String[] { "j.jetjiang@gmail.com" };  
				String subject = "email title";  
				String body = "email body";  
				intent.putExtra(android.content.Intent.EXTRA_EMAIL, reciver);  
				intent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);  
				intent.putExtra(android.content.Intent.EXTRA_TEXT, body); 
			    startActivity(intent);

相关推荐

    Android实现发送邮件

    在Android平台上实现自动发送邮件的功能是一项常见的需求,尤其对于开发者来说,这可能涉及到通知、日志分享或者其他自动化操作。为了实现这一功能,我们需要利用JavaMail API以及SMTP(Simple Mail Transfer ...

    Android自带的邮件发送代码

    在Android平台上,开发人员可以利用内置的SMTP(Simple Mail Transfer Protocol)支持来实现邮件发送功能。这个过程涉及到多个步骤和关键知识点,包括设置权限、构建邮件消息对象、选择邮件服务提供商以及处理网络...

    android邮件发送几种方式

    下面将详细介绍几种常见的Android邮件发送方式。 1. **使用Intent启动邮件应用** Android系统内置了对邮件应用的支持,可以通过Intent来启动邮件客户端。这种方式简单易用,但缺点是用户必须安装了邮件客户端应用...

    Android发送邮件demo

    在Android平台上,发送邮件功能是常见的需求,无论是用于用户反馈、分享内容还是自动化服务。本文将深入探讨如何在Android应用中实现后台发送邮件以及如何调用第三方程序来完成这一任务。 首先,Android发送邮件...

    android后台自动发邮件所需jar包

    在Android平台上实现后台自动发送邮件的功能,通常需要借助一些特定的库文件,这些库文件以Java Archive (JAR)格式存在。在这个场景中,我们有三个关键的JAR包:mail.jar、activation.jar和additionnal.jar。这些JAR...

    android 后台发送邮件

    在Android平台上实现后台发送邮件是一项常见的任务,尤其对于那些需要自动通知、消息推送或数据同步的应用来说。在本文中,我们将深入探讨如何在Android后台环境中有效地实现这一功能,以及涉及的相关知识点。 首先...

    Android高级应用源码-Android调用谷歌STMP发送邮件 MailDemo.zip

    这份"Android高级应用源码-Android调用谷歌STMP发送邮件 MailDemo.zip"提供了完整的示例代码,帮助开发者理解并实现这一功能。下面我们将深入探讨相关知识点。 1. **Android编程基础** Android是一个基于Linux内核...

    android 自动发送邮件

    android 有时候 出现错误的时候,需要将错误通过邮件发送给 开发者,以便开发者可以改进。网上找了很多例子,大部分都是通过 android 自带api 使用 Intent 调用...本例子 结合了网上例子,使用JavaMai自动发送邮件。

    Android自动发送邮件所需的4个jar包

    在Android平台上,有时候我们需要实现应用程序自动发送邮件的功能,例如用于通知、反馈或系统错误报告等。这个过程通常涉及到一些特定的库和配置。在提供的信息中,“Android自动发送邮件所需的4个jar包”是一个关键...

    Android后台发送邮件

    在Android平台上实现后台发送邮件是一项常见的任务,尤其对于那些需要自动同步或通知功能的应用来说。在后台发送邮件意味着用户无需直接操作应用,程序会在适当的时机默默地执行发送过程,只要设备有网络连接。以下...

    Android程序崩溃异常处理之自动发送邮件

    通过以上步骤,我们已经实现了Android程序在崩溃时自动发送邮件的功能。邮件中不仅包含了崩溃日志,还可以根据需要附加其他相关信息,如设备信息、用户操作日志等,以便更全面地分析问题原因。这种机制能够帮助...

    Android 后台发送邮件

    在Android平台上实现后台发送邮件的功能是一项常见的需求,尤其在用户注册、找回密码等场景中,自动发送验证邮件或通知信息显得尤为重要。本教程将详细讲解如何利用JavaMail API和Android的相关技术来实现在Android...

    android自动发送邮件(含附件)

    在Android平台上,自动发送邮件是一项常见的功能,尤其对于开发者来说,可能需要在应用程序中集成这一特性,例如用于错误报告或用户反馈。JavaMail是实现这一功能的一个关键库,它允许我们在Android应用中发送电子...

    发邮件Demo_Android

    在Android开发中,有时我们需要实现应用程序在用户无感知的情况下自动发送邮件功能,这通常涉及到服务(Service)的使用以及SMTP协议的实现。"发邮件Demo_Android"是一个针对这一需求的示例项目,它演示了如何在不...

    基于android邮件系统

    【基于Android邮件系统】是一种专为Android平台设计的移动邮件应用程序,它允许用户在智能手机上方便地接收和发送电子邮件。这种系统充分利用了Android操作系统的优势,提供了便捷、高效的邮件管理功能,让用户可以...

    Android邮件客户端Demo

    在Android邮件客户端Demo中,JavaMail被用来实现邮件的发送和接收功能。开发者可以使用它来连接邮件服务器,执行身份验证,处理邮件头信息,以及管理邮件的附件。 2. **POP3和SMTP协议**:POP3(Post Office ...

    Python-钉钉自动上下班打卡辅助基于Pythonadb实现打卡后自动发送邮件提醒

    【Python-钉钉自动上下班打卡辅助基于Pythonadb实现打卡后自动发送邮件提醒】 这个项目是利用Python编程语言,结合Android Debug Bridge(ADB)工具,为钉钉应用创建的一个自动化辅助程序,主要用于自动完成上下班...

Global site tag (gtag.js) - Google Analytics