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不支持自动发送,但又是默认邮件客户端,所以需要添加自动发送功能。主要实现步骤为:
编写一个自动发送邮件类
主要功能为:接收用户输入,组装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("com.android.email.intent.action.sendInBack");
- * String[] reciver = new String[] { "your_name@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);
- * </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。
-----摘自疯狂程序员|Crazy Coder
------博客链接http://melord.iteye.com/blog/1471838