编写好邮件点击发送,代码执行MessageCompose.java 中的(邮件的编写,及添加附件都在这个类中处理

privatevoidsendOrSaveMessage(booleansend){if(!mMessageLoaded){Log.w(Logging.LOG_TAG,"Attemptedtosavedraftmessagepriortothestatebeingfullyloaded");return;}synchronized(sActiveSaveTasks){mLastSaveTaskId=sNextSaveTaskId++;SendOrSaveMessageTasktask=newSendOrSaveMessageTask(mLastSaveTaskId,send);//Ensurethetasksareexecutedseriallysothatrapidschedulingdoesn'tresult//ininconsistentdata.//task.executeSerial();}}

privateclassSendOrSaveMessageTaskextendsEmailAsyncTask<Void,Void,Long>{privatefinalbooleanmSend;privatefinallongmTaskId;/**Acontextthatwillsurviveevenpastactivitydestruction.*/privatefinalContextmContext;publicSendOrSaveMessageTask(longtaskId,booleansend){super(null/*DONOTcancelinonDestroy*/);if(send&&ActivityManager.isUserAMonkey()){Log.d(Logging.LOG_TAG,"Inhibitingsendwhilemonkeyisincharge.");send=false;}mTaskId=taskId;mSend=send;mContext=getApplicationContext();sActiveSaveTasks.put(mTaskId,this);}@OverrideprotectedLongdoInBackground(Void...params){synchronized(mDraft){updateMessage(mDraft,mAccount,mAttachments.size()>0,mSend);ContentResolverresolver=getContentResolver();if(mDraft.isSaved()){//UpdatethemessageUridraftUri=ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI,mDraft.mId);resolver.update(draftUri,getUpdateContentValues(mDraft),null,null);//UpdatethebodyContentValuesvalues=newContentValues();values.put(BodyColumns.TEXT_CONTENT,mDraft.mText);values.put(BodyColumns.TEXT_REPLY,mDraft.mTextReply);values.put(BodyColumns.HTML_REPLY,mDraft.mHtmlReply);values.put(BodyColumns.INTRO_TEXT,mDraft.mIntroText);values.put(BodyColumns.SOURCE_MESSAGE_KEY,mDraft.mSourceKey);Body.updateBodyWithMessageId(MessageCompose.this,mDraft.mId,values);}else{//mDraft.mIdissetuponreturnofsaveToMailbox()mController.saveToMailbox(mDraft,Mailbox.TYPE_DRAFTS);}//Foranyunloadedattachment,settheflagsayingweneeditloadedbooleanhasUnloadedAttachments=false;//mAttachments处理附件部分-----开始for(Attachmentattachment:mAttachments){if(attachment.mContentUri==null&&((attachment.mFlags&Attachment.FLAG_SMART_FORWARD)==0)){attachment.mFlags|=Attachment.FLAG_DOWNLOAD_FORWARD;hasUnloadedAttachments=true;if(Email.DEBUG){Log.d(Logging.LOG_TAG,"Requestingdownloadofattachment#"+attachment.mId);}}//MakesuretheUIversionoftheattachmenthasthenow-correctid;wewill//usetheidagainwhencomingbackfrompickingnewattachmentsif(!attachment.isSaved()){//thisattachmentisnewsosaveittoDB.attachment.mMessageKey=mDraft.mId;attachment.save(MessageCompose.this);}elseif(attachment.mMessageKey!=mDraft.mId){//Weclonetheattachmentandsaveitagain;otherwise,itwill//continuetopointtothesourcemessage.Fromthispointforward,//theattachmentswillbeindependentoftheoriginalmessageinthe//database;however,westillneedthemessageontheserverinorder//toretrieveunloadedattachmentsattachment.mMessageKey=mDraft.mId;//attachment.toContentValues()是最重要的,因为在toContentValues()这里是将所有关于附件的信息都put到了//ContentValues中,然后执行insert后,发送的邮件附件信息就存储在了数据表中,也就是在toContentValues中的时候//中文名就会出现解码乱码问题,具体看下面贴出的代码部分。ContentValuescv=attachment.toContentValues();cv.put(Attachment.FLAGS,attachment.mFlags);cv.put(Attachment.MESSAGE_KEY,mDraft.mId);getContentResolver().insert(Attachment.CONTENT_URI,cv);}}//处理附件部分-----结束if(mSend){//Lettheuserknowifmessagesendingmightbedelayedbybackground//downladingofunloadedattachmentsif(hasUnloadedAttachments){Utility.showToast(MessageCompose.this,R.string.message_view_attachment_background_load);}mController.sendMessage(mDraft);ArrayList<CharSequence>addressTexts=newArrayList<CharSequence>();addressTexts.add(mToView.getText());addressTexts.add(mCcView.getText());addressTexts.add(mBccView.getText());DataUsageStatUpdaterupdater=newDataUsageStatUpdater(mContext);updater.updateWithRfc822Address(addressTexts);}returnmDraft.mId;}}privatebooleanshouldShowSaveToast(){//Don'tshowthetoastwhenrotating,orwhenopeninganActivityontopofthisone.return!isChangingConfigurations()&&!mPickingAttachment;}@OverrideprotectedvoidonSuccess(LongdraftId){//Notethatsendorsavetasksarealwayscompleted,eveniftheactivity//finishesearlier.sActiveSaveTasks.remove(mTaskId);//Don'tdisplaythetoastiftheuserisjustchangingtheorientationif(!mSend&&shouldShowSaveToast()){Toast.makeText(mContext,R.string.message_saved_toast,Toast.LENGTH_LONG).show();}}}


就上面附件注释部分说的,附件信息解析并添加到数据表中,主要是在 com.android.emailcommon.provider中的EmailContent中,里面有对个Message 数据解析处理模块。下面看对附件部分的解析。

@OverridepublicContentValuestoContentValues(){Log.i("EmailContent","toContentValues---->mFileName:"+mFileName+"mContentUri:"+mContentUri+"===mEncoding==="+mEncoding);//这里就是对附件mFileName为中文时编码处理,否则就会乱码,至于用mEncoding是否为空来判断是否//对附件名做编码处理,是因为在解决这个问题反复测试发现,如果PC端发邮件,android应用端接受邮件,mEncoding会//有编码值,如果这里做了加密及强制转换编码,那么客户端接受到的附件,因为做了下面处理就也会出现乱码,所以我们是//不处理的。但是客户端发出去邮件时mEncoding始终会是NULL,最终添加到表中时,Exchange服务类型的编码会是//base64,至于在什么地方给处理的没研究太深,POP,IMAP的mEncoding却是NULL(我也不知到在哪处理的,没时间研究啊)//如果大家发现不有特殊情况的话,欢迎纠正。。。谢谢啦if(TextUtils.isEmpty(mEncoding)){mFileName=MimeUtility.foldAndEncode2(mFileName,"Content-Disposition".length()+2);}Log.i("EmailContent","toContentValues--1-->"+mFileName);ContentValuesvalues=newContentValues();values.put(AttachmentColumns.FILENAME,mFileName);values.put(AttachmentColumns.MIME_TYPE,mMimeType);values.put(AttachmentColumns.SIZE,mSize);values.put(AttachmentColumns.CONTENT_ID,mContentId);values.put(AttachmentColumns.CONTENT_URI,mContentUri);values.put(AttachmentColumns.MESSAGE_KEY,mMessageKey);values.put(AttachmentColumns.LOCATION,mLocation);values.put(AttachmentColumns.ENCODING,mEncoding);values.put(AttachmentColumns.CONTENT,mContent);values.put(AttachmentColumns.FLAGS,mFlags);values.put(AttachmentColumns.CONTENT_BYTES,mContentBytes);values.put(AttachmentColumns.ACCOUNT_KEY,mAccountKey);values.put(AttachmentColumns.UI_STATE,mUiState);values.put(AttachmentColumns.UI_DESTINATION,mUiDestination);values.put(AttachmentColumns.UI_DOWNLOADED_SIZE,mUiDownloadedSize);returnvalues;}

对于上面在往表里put 数据的时候对附件名称做了处理那么。在显示名称时当然也要解密

如下:

@Overridepublicvoidrestore(Cursorcursor){mBaseUri=CONTENT_URI;mId=cursor.getLong(CONTENT_ID_COLUMN);mEncoding=cursor.getString(CONTENT_ENCODING_COLUMN);mFileName=cursor.getString(CONTENT_FILENAME_COLUMN);Log.i("EmailContent","restore-->mFileName:"+mFileName+"mEncoding:"+mEncoding);if(TextUtils.isEmpty(mEncoding)){mFileName=MimeUtility.unfoldAndDecode(mFileName);}Log.i("EmailContent","restore-->mFileName:"+mFileName);mMimeType=cursor.getString(CONTENT_MIME_TYPE_COLUMN);mSize=cursor.getLong(CONTENT_SIZE_COLUMN);mContentId=cursor.getString(CONTENT_CONTENT_ID_COLUMN);mContentUri=cursor.getString(CONTENT_CONTENT_URI_COLUMN);mMessageKey=cursor.getLong(CONTENT_MESSAGE_ID_COLUMN);mLocation=cursor.getString(CONTENT_LOCATION_COLUMN);mContent=cursor.getString(CONTENT_CONTENT_COLUMN);mFlags=cursor.getInt(CONTENT_FLAGS_COLUMN);mContentBytes=cursor.getBlob(CONTENT_CONTENT_BYTES_COLUMN);mAccountKey=cursor.getLong(CONTENT_ACCOUNT_KEY_COLUMN);mUiState=cursor.getInt(CONTENT_UI_STATE_COLUMN);mUiDestination=cursor.getInt(CONTENT_UI_DESTINATION_COLUMN);mUiDownloadedSize=cursor.getInt(CONTENT_UI_DOWNLOADED_SIZE_COLUMN);}

以上是针对Exchange 服务 中文乱码问题解决,因为 原生代码中,使用Exchange 登录邮箱,发送邮件,与使用POP,IMAP不是走同一个流程,具体看Controller.java中

publicvoidsendPendingMessages(longaccountId){//1.makesureweevenhaveanoutbox,exitearlyifnotfinallongoutboxId=Mailbox.findMailboxOfType(mProviderContext,accountId,Mailbox.TYPE_OUTBOX);if(outboxId==Mailbox.NO_MAILBOX){return;}//如果使用的是Exchange账户service便会得到值,这里是根据accountId判断是哪个服务,否则service便是NULL//2.dispatchasnecessaryIEmailServiceservice=getServiceForAccount(accountId);if(service!=null){//Serviceimplementationtry{service.startSync(outboxId,false);}catch(RemoteExceptione){//TODOChangeexceptionhandlingtobeconsistentwithhoweverthismethod//isimplementedforotherprotocolsLog.d("updateMailbox","RemoteException"+e);}}else{//MessagingControllerimplementationsendPendingMessagesSmtp(accountId);}}

再看sendPendingMessagesSmtp() 方法中执行了

mLegacyController.sendPendingMessages(account,sentboxId,mLegacyListener);

然后

publicvoidsendPendingMessagesSynchronous(finalAccountaccount,longsentFolderId){TrafficStats.setThreadStatsTag(TrafficFlags.getSmtpFlags(mContext,account));NotificationControllernc=NotificationController.getInstance(mContext);//1.Loopthroughallmessagesintheaccount'soutboxlongoutboxId=Mailbox.findMailboxOfType(mContext,account.mId,Mailbox.TYPE_OUTBOX);if(outboxId==Mailbox.NO_MAILBOX){return;}ContentResolverresolver=mContext.getContentResolver();Cursorc=resolver.query(EmailContent.Message.CONTENT_URI,EmailContent.Message.ID_COLUMN_PROJECTION,EmailContent.Message.MAILBOX_KEY+"=?",newString[]{Long.toString(outboxId)},null);try{//2.exitearlyif(c.getCount()<=0){return;}//3.doone-timesetupoftheSender&otherstuffmListeners.sendPendingMessagesStarted(account.mId,-1);//注意,下面这一行便是处理POP,IMAP服务的Sender类,该sender是父类POP,IMAP最终走的是//com.android.email.mail.transport包下的SmtpSender类,也就是下面执行的sender.sendMessage(messageId)//最终是执行的SmtpSender中的sendMessage方法。Sendersender=Sender.getInstance(mContext,account);StoreremoteStore=Store.getInstance(account,mContext);booleanrequireMoveMessageToSentFolder=remoteStore.requireCopyMessageToSentFolder();ContentValuesmoveToSentValues=null;if(requireMoveMessageToSentFolder){moveToSentValues=newContentValues();moveToSentValues.put(MessageColumns.MAILBOX_KEY,sentFolderId);}booleanfaild=false;//4.loopthroughtheavailablemessagesandsendthemwhile(c.moveToNext()){longmessageId=-1;try{messageId=c.getLong(0);mListeners.sendPendingMessagesStarted(account.mId,messageId);//Don'tsendmessageswithunloadedattachmentsif(Utility.hasUnloadedAttachments(mContext,messageId)){if(Email.DEBUG){Log.d(Logging.LOG_TAG,"Can'tsend#"+messageId+";unloadedattachments");}continue;}sender.sendMessage(messageId);}catch(MessagingExceptionme){//reporterrorforthismessage,butkeeptryingothersif(meinstanceofAuthenticationFailedException){nc.showLoginFailedNotification(account.mId);}faild=true;handler.sendEmptyMessage(1);mListeners.sendPendingMessagesFailed(account.mId,messageId,me);continue;}//5.movetosent,ordeleteUrisyncedUri=ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI,messageId);if(requireMoveMessageToSentFolder){//Ifthisisaforwardedmessageandithasattachments,deletethem,asthey//duplicateinformationfoundelsewhere(ontheserver).Thissavesstorage.EmailContent.Messagemsg=EmailContent.Message.restoreMessageWithId(mContext,messageId);if(msg!=null&&((msg.mFlags&EmailContent.Message.FLAG_TYPE_FORWARD)!=0)){AttachmentUtilities.deleteAllAttachmentFiles(mContext,account.mId,messageId);}resolver.update(syncedUri,moveToSentValues,null,null);}else{AttachmentUtilities.deleteAllAttachmentFiles(mContext,account.mId,messageId);Uriuri=ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI,messageId);resolver.delete(uri,null,null);resolver.delete(syncedUri,null,null);}}//6.reportcompletion/successif(!faild){handler.sendEmptyMessage(0);}mListeners.sendPendingMessagesCompleted(account.mId);nc.cancelLoginFailedNotification(account.mId);}catch(MessagingExceptionme){if(meinstanceofAuthenticationFailedException){nc.showLoginFailedNotification(account.mId);}handler.sendEmptyMessage(1);mListeners.sendPendingMessagesFailed(account.mId,-1,me);}finally{c.close();}}

在 SmtpSender 的sendMessage 中有一个

Rfc822Output.writeTo(mContext,messageId,newEOLConvertingOutputStream(mTransport.getOutputStream()),false/*donotusesmartreply*/,false/*donotsendBCC*/);

在这里就是对POP,IMAP 的邮件信息处理,至于这里怎么解决邮件发送 中文名附件出现乱码,就参考下面的网址吧,

偷懒不想写了 ^_^,

http://blog.csdn.net/jaycee110905/article/details/17677931


更多相关文章

  1. android中使用javamail发送邮件附件
  2. Android(安卓)Series: GET, POST and Multipart POST 请求
  3. AndroidManifest.xml反编译
  4. Android发送邮件的方法实例详解
  5. Android向Excel写入数据导出U盘并发送邮件
  6. 使用Android(安卓)Studio遇到的一些常见问题总结
  7. 将Outlook.com添加到Android设备
  8. android pop3与imap方式接收邮件(javamail)
  9. JAVA/Android(安卓)读写文件,避免中文乱码 FileWriter乱码

随机推荐

  1. 自定义Android(安卓)Progress Bar的颜色
  2. Android(安卓)Robotium的自动化代码
  3. android中全屏显示
  4. ‘void android.view.View.dispatchDetac
  5. (Android) Eclipse "launching delegate"
  6. Android写文件到Sd卡的一般过程
  7. android判断网络
  8. Android(安卓)获取手机的一些基本信息类
  9. android监听短信并判断是否未读
  10. Android(安卓)自定义BaseAdapter