发送email
来源:互联网 发布:python json encode 编辑:程序博客网 时间:2024/05/17 23:34
1 sendOrSaveMessage:调用updateMessage方法更新displayname;
2 sendMessage and save:发送邮件同时保存邮件时调用message.save()方法;
sendPendingMessagesSynchronous:更新mailboxId将邮件从发件箱移到已发送邮件
代码详细分析:
MessageCompose.java
当用户编辑完成后点击发送按钮,则触发MessageCompose.java的onsend()方法:
privatevoid onSend() {
if (!isAddressAllValid()) {
Toast.makeText(this, getString(R.string.message_compose_error_invalid_email),
Toast.LENGTH_LONG).show();
} elseif (getAddresses(mToView).length == 0 &&
getAddresses(mCcView).length == 0 &&
getAddresses(mBccView).length == 0) {
mToView.setError(getString(R.string.message_compose_error_no_recipients));
Toast.makeText(this, getString(R.string.message_compose_error_no_recipients),
Toast.LENGTH_LONG).show();
} else {
sendOrSaveMessage(true);
setDraftNeedsSaving(false);
finish();
}
}
首先对收件人地址的合法性进行判断,不合法则弹出toast消息提示用户。接着调用sendOrSaveMessage()进行发送,发送完毕后执行setDraftNeedsSaving(false)表示不用保存草稿(因为发送过程中会将邮件保存在发件箱或者已发送),然后finish该Activity。
在sendOrSaveMessage()中先对mMessageLoaded进行判断,该值用于判断回复或者转发邮件时上一封邮件是否加载完毕,没有加载完毕是不会发送的。然后将当前邮件保存在数据库。然后调用Controller.java进行发送。
Controller.java
sendMessage()完成发送前的准备工作,将邮件移至发件箱(Outbox),这里是exchange的邮件发送过程与pop/imap的分岔点。
publicvoidsendMessage(long messageId,long accountId) {
ContentResolver resolver = mProviderContext.getContentResolver();
if (accountId == -1) {
accountId = lookupAccountForMessage(messageId);
}
if (accountId == -1) {
// probably the message was not found
if (Email.LOGD) {
Email.log("no account found for message " + messageId);
}
return;
}
// Move toOutbox
long outboxId = findOrCreateMailboxOfType(accountId, Mailbox.TYPE_OUTBOX);
ContentValues cv = new ContentValues();
cv.put(EmailContent.MessageColumns.MAILBOX_KEY, outboxId);
// does this need to be SYNCED_CONTENT_URI instead?
Uri uri = ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI, messageId);
resolver.update(uri, cv, null,null);
// Split here for target type (Service or MessagingController)
IEmailService service = getServiceForMessage(messageId);
if (service !=null) {
// We just need to be sure thecallback is installed, if this is the first call
// to the service.
try {
service.setCallback(mServiceCallback);
} catch (RemoteException re) {
// OK - not a criticalcallback here
}
} else {
// for IMAP & POP only, (attempt to) send the message now
final EmailContent.Account account =
EmailContent.Account.restoreAccountWithId(mProviderContext, accountId);
if (account ==null) {
return;
}
finallong sentboxId = findOrCreateMailboxOfType(accountId, Mailbox.TYPE_SENT);
/*DTS2012042101715yangjinri 20120417 begin */
finallong msgId = messageId;
new Thread() {
@Override
publicvoid run() {
boolean sendCurrentMessageOnly = (1 == Settings.Systemex.getInt(mContext.getContentResolver(),
"send_current_message_only", 0));
if (sendCurrentMessageOnly) {
mLegacyController.sendCurrentMessage(account, sentboxId,mLegacyListener, msgId);
} else {
mLegacyController.sendPendingMessages(account, sentboxId,mLegacyListener);
}
/*DTS2012042101715yangjinri 20120417 end */
}
}.start();
}
}
MessagingController.java
sendPendingMessages()方法将发件箱中的每封邮件都发送出去,并且开启一个线程来尝试完成。
publicvoid sendPendingMessages(final EmailContent.Account account, finallong sentFolderId,
MessagingListener listener) {
put("sendPendingMessages", listener,new Runnable() {
publicvoid run() {
sendPendingMessagesSynchronous(account, sentFolderId);
}
});
}
线程中的实现方法如下:
1.在outbox中循环查找需要发送的邮件
2.如果需要发送的邮件数量为0,则return
3.创建sender对象(通用的sender entries存放在senders.xml)和store对象()和store对象(通用的store entries存放在stores.xml)。
4.循环发送邮件,若一封发送失败,会continue发送下一封
5.发送成功,会将邮件转移至已发送,或者删除
publicvoidsendPendingMessagesSynchronous(final EmailContent.Account account,
long sentFolderId) {
// 1. Loop through all messages in the account's outbox
long outboxId = Mailbox.findMailboxOfType(mContext, account.mId, Mailbox.TYPE_OUTBOX);
if (outboxId == Mailbox.NO_MAILBOX) {
return;
}
ContentResolver resolver = mContext.getContentResolver();
Cursor c = resolver.query(EmailContent.Message.CONTENT_URI,
EmailContent.Message.ID_COLUMN_PROJECTION,
EmailContent.Message.MAILBOX_KEY +"=?",new String[] { Long.toString(outboxId) },
null);
try {
// 2. exit early
if (c.getCount() <= 0) {
return;
}
// 3. do one-time setup of the Sender & other stuff
mListeners.sendPendingMessagesStarted(account.mId, -1);
Sender sender = Sender.getInstance(mContext, account.getSenderUri(mContext));
Store remoteStore = Store.getInstance(account.getStoreUri(mContext),mContext,null);
boolean requireMoveMessageToSentFolder = remoteStore.requireCopyMessageToSentFolder();
ContentValues moveToSentValues = null;
if (requireMoveMessageToSentFolder) {
moveToSentValues = new ContentValues();
moveToSentValues.put(MessageColumns.MAILBOX_KEY, sentFolderId);
}
// 4. loop through the available messages and send them
/* DTS2012042101715 yangjinri 20120417 begin*/
boolean sendCurrentMessageOnly = (1 == Settings.Systemex.getInt(mContext.getContentResolver(),
"send_current_message_only", 0));
while (c.moveToNext()) {
long messageId = -1;
try {
messageId = c.getLong(0);
if (sendCurrentMessageOnly) {
if (messageId ==mMessageId) {
mListeners.sendPendingMessagesStarted(account.mId, messageId);
sender.sendMessage(messageId);
} else {
continue;
}
} else {
mListeners.sendPendingMessagesStarted(account.mId, messageId);
sender.sendMessage(messageId);
}
/* DTS2012042101715 yangjinri 20120417 end*/
} catch (MessagingException me) {
// report error for this message, but keep trying others
mListeners.sendPendingMessagesFailed(account.mId, messageId, me);
continue;
}
// 5. move to sent, or delete
Uri syncedUri =
ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI, messageId);
if (requireMoveMessageToSentFolder) {
resolver.update(syncedUri, moveToSentValues,null,null);
} else {
AttachmentProvider.deleteAllAttachmentFiles(mContext, account.mId, messageId);
Uri uri =
ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI, messageId);
resolver.delete(uri, null, null);
resolver.delete(syncedUri,null,null);
}
}
// 6. report completion/success
mListeners.sendPendingMessagesCompleted(account.mId);
} catch (MessagingException me) {
mListeners.sendPendingMessagesFailed(account.mId, -1, me);
} finally {
c.close();
}
}
SmtpSender.java
SmtpSender类继承于Sender类,实现了其sendMessage()抽象方法:
然后通过MAIL TO;RCPT TO;DATA等命令与服务器进行交互。然后将邮件用Rfc822Output.writeTo()将邮件打包成标准格式后上传给服务器。executeSimpleCommand("\r\n.")表示这次发送结束。
@Override
publicvoidsendMessage(long messageId)throws MessagingException {
close();
open();
Message message = Message.restoreMessageWithId(mContext, messageId);
if (message ==null) {
thrownew MessagingException("Trying to send non-existent message id="
+ Long.toString(messageId));
}
Address from = Address.unpackFirst(message.mFrom);
Address[] to = Address.unpack(message.mTo);
Address[] cc = Address.unpack(message.mCc);
Address[] bcc = Address.unpack(message.mBcc);
try {
executeSimpleCommand("MAIL FROM: " +"<" + from.getAddress() +">");
for (Address address : to) {
executeSimpleCommand("RCPT TO: " +"<" + address.getAddress() +">");
}
for (Address address : cc) {
executeSimpleCommand("RCPT TO: " +"<" + address.getAddress() +">");
}
for (Address address : bcc) {
executeSimpleCommand("RCPT TO: " +"<" + address.getAddress() +">");
}
executeSimpleCommand("DATA");
// TODO byte stuffing
Rfc822Output.writeTo(mContext, messageId,
new EOLConvertingOutputStream(mTransport.getOutputStream()),true,false);
executeSimpleCommand("\r\n.");
} catch (IOException ioe) {
thrownew MessagingException("Unable to send message", ioe);
}
}
- 发送Email
- EMail发送
- 发送email
- 发送email
- 发送Email
- 发送email
- 发送Email
- email 发送
- 发送email 打开email
- JSP发送EMAIL
- JSP发送EMAIL
- oracle内发送email
- java发送email
- ASP.net发送Email
- asp.net 发送email
- 用genexus发送email
- 用.net发送email
- 发送email类(C#)
- 如何去除 google+ 上的热门信息
- C++中输入输出流getline()函数用法
- Android各种单位转换&&Android的View用到的部分代码
- Design pattern and Software design interview questions for Programmers
- MH370被劫持新证据 飞机高度突降或暗示有搏斗
- 发送email
- 好书推荐:《大数据时代》
- MediaPlayer-MediaPlayerService-MediaPlayerService::Client的三角关系
- java的23种设计模式
- DCD、DTR、DSR、RTS及CTS状态指示的意义
- 关于fork()函数的精辟分析
- 按年、按月、按周、按日进行统计分析
- Cocos2d-x官方中文文档
- C++11中值得关注的几大变化