2019独角兽企业重金招聘Python工程师标准>>>

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

private void sendOrSaveMessage(boolean send) {if (!mMessageLoaded) {Log.w(Logging.LOG_TAG,"Attempted to save draft message prior to the state being fully loaded");return;}synchronized (sActiveSaveTasks) {mLastSaveTaskId = sNextSaveTaskId++;SendOrSaveMessageTask task = new SendOrSaveMessageTask(mLastSaveTaskId, send);// Ensure the tasks are executed serially so that rapid scheduling doesn't result// in inconsistent data.//task.executeSerial();}}
private class SendOrSaveMessageTask extends EmailAsyncTask<Void, Void, Long> {private final boolean mSend;private final long mTaskId;/** A context that will survive even past activity destruction. */private final Context mContext;public SendOrSaveMessageTask(long taskId, boolean send) {super(null /* DO NOT cancel in onDestroy */);if (send && ActivityManager.isUserAMonkey()) {Log.d(Logging.LOG_TAG, "Inhibiting send while monkey is in charge.");send = false;}mTaskId = taskId;mSend = send;mContext = getApplicationContext();sActiveSaveTasks.put(mTaskId, this);}@Overrideprotected Long doInBackground(Void... params) {synchronized (mDraft) {updateMessage(mDraft, mAccount, mAttachments.size() > 0, mSend);ContentResolver resolver = getContentResolver();if (mDraft.isSaved()) {// Update the messageUri draftUri =ContentUris.withAppendedId(Message.SYNCED_CONTENT_URI, mDraft.mId);resolver.update(draftUri, getUpdateContentValues(mDraft), null, null);// Update the bodyContentValues values = new ContentValues();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.mId is set upon return of saveToMailbox()mController.saveToMailbox(mDraft, Mailbox.TYPE_DRAFTS);}// For any unloaded attachment, set the flag saying we need it loadedboolean hasUnloadedAttachments = false;//mAttachments 处理附件部分 -----开始for (Attachment attachment : 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,"Requesting download of attachment #" + attachment.mId);}}// Make sure the UI version of the attachment has the now-correct id; we will// use the id again when coming back from picking new attachmentsif (!attachment.isSaved()) {// this attachment is new so save it to DB.attachment.mMessageKey = mDraft.mId;attachment.save(MessageCompose.this);} else if (attachment.mMessageKey != mDraft.mId) {// We clone the attachment and save it again; otherwise, it will// continue to point to the source message.  From this point forward,// the attachments will be independent of the original message in the// database; however, we still need the message on the server in order// to retrieve unloaded attachmentsattachment.mMessageKey = mDraft.mId;
//attachment.toContentValues()是最重要的,因为在toContentValues()这里 是将所有关于附件的信息都put 到了
//ContentValues 中,然后执行  insert后,发送的邮件附件信息就存储在了数据表中,也就是在toContentValues中的时候
//中文名就会出现解码 乱码问题,具体看下面贴出的代码部分。ContentValues cv = attachment.toContentValues();cv.put(Attachment.FLAGS, attachment.mFlags);cv.put(Attachment.MESSAGE_KEY, mDraft.mId);getContentResolver().insert(Attachment.CONTENT_URI, cv);}}//处理附件部分 -----结束if (mSend) {// Let the user know if message sending might be delayed by background// downlading of unloaded attachmentsif (hasUnloadedAttachments) {Utility.showToast(MessageCompose.this,R.string.message_view_attachment_background_load);}mController.sendMessage(mDraft);ArrayList<CharSequence> addressTexts = new ArrayList<CharSequence>();addressTexts.add(mToView.getText());addressTexts.add(mCcView.getText());addressTexts.add(mBccView.getText());DataUsageStatUpdater updater = new DataUsageStatUpdater(mContext);updater.updateWithRfc822Address(addressTexts);}return mDraft.mId;}}private boolean shouldShowSaveToast() {// Don't show the toast when rotating, or when opening an Activity on top of this one.return !isChangingConfigurations() && !mPickingAttachment;}@Overrideprotected void onSuccess(Long draftId) {// Note that send or save tasks are always completed, even if the activity// finishes earlier.sActiveSaveTasks.remove(mTaskId);// Don't display the toast if the user is just changing the orientationif (!mSend && shouldShowSaveToast()) {Toast.makeText(mContext, R.string.message_saved_toast, Toast.LENGTH_LONG).show();}}}

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

 @Overridepublic ContentValues toContentValues() {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);ContentValues values = new ContentValues();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);return values;}

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

如下:

@Overridepublic void restore(Cursor cursor) {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中

 public void sendPendingMessages(long accountId) {// 1. make sure we even have an outbox, exit early if notfinal long outboxId =Mailbox.findMailboxOfType(mProviderContext, accountId, Mailbox.TYPE_OUTBOX);if (outboxId == Mailbox.NO_MAILBOX) {return;}
//如果使用的是Exchange 账户service便会得到值,这里是根据accountId判断是哪个服务,否则service便是NULL// 2. dispatch as necessaryIEmailService service = getServiceForAccount(accountId);if (service != null) {// Service implementationtry {service.startSync(outboxId, false);} catch (RemoteException e) {// TODO Change exception handling to be consistent with however this method// is implemented for other protocolsLog.d("updateMailbox", "RemoteException" + e);}} else {// MessagingController implementationsendPendingMessagesSmtp(accountId);}}

再看sendPendingMessagesSmtp() 方法中执行了

mLegacyController.sendPendingMessages(account, sentboxId, mLegacyListener);

然后

public void sendPendingMessagesSynchronous(final Account account,long sentFolderId) {TrafficStats.setThreadStatsTag(TrafficFlags.getSmtpFlags(mContext, account));NotificationController nc = NotificationController.getInstance(mContext);// 1.  Loop through all messages in the account's outboxlong 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 earlyif (c.getCount() <= 0) {return;}// 3. do one-time setup of the Sender & other stuffmListeners.sendPendingMessagesStarted(account.mId, -1);
//注意,下面这一行便是处理POP,IMAP 服务的Sender 类,该 sender是父类 POP,IMAP最终走的是
//com.android.email.mail.transport包下的SmtpSender类,也就是下面执行的 sender.sendMessage(messageId)
//最终是执行的SmtpSender中的sendMessage方法。Sender sender = Sender.getInstance(mContext, account);Store remoteStore = Store.getInstance(account, mContext);boolean requireMoveMessageToSentFolder = remoteStore.requireCopyMessageToSentFolder();ContentValues moveToSentValues = null;if (requireMoveMessageToSentFolder) {moveToSentValues = new ContentValues();moveToSentValues.put(MessageColumns.MAILBOX_KEY, sentFolderId);}boolean faild =false;// 4.  loop through the available messages and send themwhile (c.moveToNext()) {long messageId = -1;try {messageId = c.getLong(0);mListeners.sendPendingMessagesStarted(account.mId, messageId);// Don't send messages with unloaded attachmentsif (Utility.hasUnloadedAttachments(mContext, messageId)) {if (Email.DEBUG) {Log.d(Logging.LOG_TAG, "Can't send #" + messageId +"; unloaded attachments");}continue;}sender.sendMessage(messageId);} catch (MessagingException me) {// report error for this message, but keep trying othersif (me instanceof AuthenticationFailedException) {nc.showLoginFailedNotification(account.mId);}faild = true;handler.sendEmptyMessage(1);mListeners.sendPendingMessagesFailed(account.mId, messageId, me);continue;}// 5. move to sent, or deleteUri syncedUri =ContentUris.withAppendedId(EmailContent.Message.SYNCED_CONTENT_URI, messageId);if (requireMoveMessageToSentFolder) {// If this is a forwarded message and it has attachments, delete them, as they// duplicate information found elsewhere (on the server).  This saves storage.EmailContent.Message msg =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);Uri uri =ContentUris.withAppendedId(EmailContent.Message.CONTENT_URI, messageId);resolver.delete(uri, null, null);resolver.delete(syncedUri, null, null);}}// 6. report completion/successif(!faild){handler.sendEmptyMessage(0);}mListeners.sendPendingMessagesCompleted(account.mId);nc.cancelLoginFailedNotification(account.mId);} catch (MessagingException me) {if (me instanceof AuthenticationFailedException) {nc.showLoginFailedNotification(account.mId);}handler.sendEmptyMessage(1);mListeners.sendPendingMessagesFailed(account.mId, -1, me);} finally {c.close();}}

在 SmtpSender 的sendMessage 中有一个

 Rfc822Output.writeTo(mContext, messageId,new EOLConvertingOutputStream(mTransport.getOutputStream()),false /* do not use smart reply */,false /* do not send BCC */);

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

偷懒不想写了  ^_^,

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

转载于:https://my.oschina.net/u/563014/blog/368150

android 原生 电子邮件 应用 发送邮件附带 中文名附件时 附件名称乱码问题解决...相关推荐

  1. 关于发送邮件附件中文文件名称乱码的问题

    问题描述:发送压缩文件到qq邮箱,发现标题为中文名称,能正常显示,但是附件的中文名称为乱码. 任务:解决附件中文名称的乱码问题. 前期资料总结: 1.SMTP乱码解决方案(源自https://blog ...

  2. 提供一个Android原生的Progress——SwipeToRefreshLayout下拉刷新时的等待动画

    先来上个图看看效果: 这里我为什么要单独把这个拿出来呢,因为最近才开始接触Android最新的东西,也就是5.0以上的东西,发现Android提供的SwipeToRefreshLayout是没有上拉加 ...

  3. Android WebView中使用loadData时出现的乱码问题解决办法

    本篇文章整理了关于安卓开发过程中使用 WebView 的loadData方法加载数据的乱码问题的解决办法,关于更多解决办法,欢迎回复整理,谢谢 方法一. 使用loadDataWithBaseURL方法 ...

  4. android原生插件,适用于 Android 的原生 (C++) 插件

    扩展 UnityPlayerActivity Java 代码 使用 Java 或 Kotlin 源文件作为插件 适用于 Android 的原生 (C++) 插件 Unity 支持用 C/C ++ 编写 ...

  5. Android 原生控件之一 TextView

    Android 原生控件之一 TextView 前言 来源 开始 XML属性 1.android:allowUndo 2.android:autoLink 3.android:autoSizeMaxT ...

  6. 基于Android原生开发的理财小助手APP

    一.实验题目 个人理财小助手 二.实验目的 掌握 SQLite 数据库及其使用. 熟练掌握布局及常用控件 Button.ListView.EditText.TextView 等. 三.总体设计 (含背 ...

  7. unity集成android原生录音(可后台)并实现上传

    Demo下载链接:https://download.csdn.net/download/a8856621/10911209 一.  首先实现android原生的录音功能,这里使用Android的Ser ...

  8. 介绍一款比Android原生模拟器还要快的模拟器Genymotion(转)

    源:介绍一款比Android原生模拟器还要快的模拟器Genymotion

  9. Android原生(Native)C开发之二 framebuffer篇

    为什么80%的码农都做不了架构师?>>>    Android原生(Native)C开发之二 framebuffer篇 如对Android原生(Natvie)C开发还任何疑问,请参阅 ...

最新文章

  1. Android源代码下载与编译 - 2019
  2. Xamarin Android设置界面提示类型错误
  3. 谈谈varnish、squid、apache、nginx缓存的对比
  4. 中国金刚石线行业“十四五规划”与未来产销需求预测报告2021-2027年
  5. mysql cascaded local_学习笔记-mysql_视图
  6. python摄像头推流_树莓派使用python-librtmp实现rtmp推流h264的方法
  7. 巧用 Lazy 解决.NET Core中的循环依赖关系
  8. HOW-TO:在Spring 4和Java 7中使用@PropertySource批注
  9. NotifyMyFrontEnd 函数背后的数据缓冲区(一)
  10. PyTorch入门-词向量
  11. 基于python的分类模型_python SVM 线性分类模型的实现
  12. QuickLook 空格键预览文件工具
  13. 网络创新激活西部科技,戴尔2013软件定义网络圆桌会谈的启示
  14. rrdtool安装编译提示错误:Can’t locate ExtUtils/MakeMaker.pm in @INC
  15. Divide Two Integers leetcode java
  16. python3 urlencode_Python3 parse.urlencode() 与parse.unquote()
  17. linux yum apr,CentOS安装、配置APR和tomcat
  18. 反常识—股票暴跌收益会更高
  19. Qt编写安防视频监控系统46-视频存储
  20. 【综合评价方法 熵权法】指标权重确定方法之熵权法

热门文章

  1. 121 项目 024 笔记向 内省机制
  2. DataX实现oracle到oracle之间的数据传递
  3. 嵌入式Linux之旅——环境搭建篇之烧写整个系统
  4. 表达式求值(from leetcode 241)
  5. 函数用法r语言_R语言中的apply函数族
  6. python上传文件到windows_python使用win32gui上传文件
  7. iPhone开发之第三方回调函数的使用方法
  8. 编程修养 阅读笔记二
  9. Project: 项目经理新建资源预订
  10. 安全小测试:介绍一个简单web安全知识测试的网站