SMS-MMS的草稿箱
2016-02-29 18:58
344 查看
Android4.2
1.草稿箱---存储。(ComposeMessageActivity)(type=3)
onKeyDown方法的case KeyEvent.KEYCODE_BACK:调用了exitComposeMessageActivity方法,主要判断离开时是否应该存储界面内的信息,或者提示信息会被舍弃,如果需要存储则把mToastForDraftSave设为true,这个参数决定了在saveDraft方法存储时给toast提示。
在onStop方法中调用了saveDraft(true)方法存储草稿。在saveDraft方法内,判断 如果不应该存储并且联系人编辑框不可见或者里面没联系人,则mWorkingMessage.discard()舍弃信息,discard()舍弃的过程为:把mDiscarded设置为true,接着删除可能存在的与此thread_Id关联的draft。
清除数据库中对应thread_id草稿,彩信的条件为
如果没舍弃信息,则调用mWorkingMessage.saveDraft(isStopping)存储。
存短信的具体代码如下(按理说不应该存在thread_id=0的数据):(测试mMessageUri == null,新建下方法不被调用,另一种情况应该是打开草稿的情况)
2、加载(WorkingMessage、DraftCache、Conversation)
在Activity的onStart方法及ListView的size变化时都会调用loadMessagesAndDraft()方法,这个方法会调用loadMessageContent()方法加载数据库里的短彩信。接着调用loadDraft()方法加载草稿箱。通过WorkingMessage.loadDraft方法查询草稿箱。在WorkingMessage的loadDraft方法里用异步线程查询,调用readDraftSmsMessage(Conversation conv)方法,此方法里做了限制,如果要查询的thread_id<=0或者!conv.hasDraft()则不查询返回
总结:很明显,如果conv.hasDraft()为false是得不到草稿信息的,Conversation的hasDraft方法实际调用DraftCache.getInstance().hasDraft(mThreadId),而DraftCache的hasDraft则是判断这个thread_id有没有在里面的HashSet中记录。
疑问:DraftCache什么时候得到草稿箱的thread_id?
在程序初始化时,在MmsApp的onCreate中调用了DraftCache.init()方法,此方法中构造了单例DraftCache对象,构造时调用refresh()方法,再里面调用rebuildCache()方法获取数据库内所有有草稿的thread_id给静态Hashset对象mDraftSet。在保存、
注意:当离开短信界面时onStop方法里调用的saveDraft(boolean isStopping)方法里
1.草稿箱---存储。(ComposeMessageActivity)(type=3)
onKeyDown方法的case KeyEvent.KEYCODE_BACK:调用了exitComposeMessageActivity方法,主要判断离开时是否应该存储界面内的信息,或者提示信息会被舍弃,如果需要存储则把mToastForDraftSave设为true,这个参数决定了在saveDraft方法存储时给toast提示。
在onStop方法中调用了saveDraft(true)方法存储草稿。在saveDraft方法内,判断 如果不应该存储并且联系人编辑框不可见或者里面没联系人,则mWorkingMessage.discard()舍弃信息,discard()舍弃的过程为:把mDiscarded设置为true,接着删除可能存在的与此thread_Id关联的draft。
if (mHasMmsDraft) { asyncDeleteDraftMmsMessage(mConversation); } if (mHasSmsDraft) { asyncDeleteDraftSmsMessage(mConversation); }
清除数据库中对应thread_id草稿,彩信的条件为
// If the thread id is < 1, then the thread_id in the pdu will be "" or NULL. We have // to clear those messages as well as ones with a valid thread id. final String where = Mms.THREAD_ID + (threadId > 0 ? " = " + threadId : " IS NULL"); asyncDelete(Mms.Draft.CONTENT_URI, where, null);短信则清除type=3的数据
if (threadId > 0) { asyncDelete(ContentUris.withAppendedId(Sms.Conversations.CONTENT_URI, threadId), SMS_DRAFT_WHERE, null); }清除mWorkingMessage内Conversation对象的thread_Id参数。
如果没舍弃信息,则调用mWorkingMessage.saveDraft(isStopping)存储。
public void saveDraft(final boolean isStopping) { // If we have discarded the message, just bail out. if (mDiscarded) { LogTag.warn("saveDraft mDiscarded: true mConversation: " + mConversation + " skipping saving draft and bailing"); return; } // Make sure setConversation was called. if (mConversation == null) { throw new IllegalStateException("saveDraft() called with no conversation"); } if (LogTag.VERBOSE || Log.isLoggable(LogTag.APP, Log.VERBOSE)) { LogTag.debug("saveDraft for mConversation " + mConversation); } // Get ready to write to disk. But don't notify message status when saving draft prepareForSave(false /* notify */); if (requiresMms()) { if (hasMmsContentToSave()) { asyncUpdateDraftMmsMessage(mConversation, isStopping); mHasMmsDraft = true; } } else { String content = mText.toString(); // bug 2169583: don't bother creating a thread id only to delete the thread // because the content is empty. When we delete the thread in updateDraftSmsMessage, // we didn't nullify conv.mThreadId, causing a temperary situation where conv // is holding onto a thread id that isn't in the database. If a new message arrives // and takes that thread id (because it's the next thread id to be assigned), the // new message will be merged with the draft message thread, causing confusion! if (!TextUtils.isEmpty(content)) { asyncUpdateDraftSmsMessage(mConversation, content, isStopping); mHasSmsDraft = true; } else { // When there's no associated text message, we have to handle the case where there // might have been a previous mms draft for this message. This can happen when a // user turns an mms back into a sms, such as creating an mms draft with a picture, // then removing the picture. asyncDeleteDraftMmsMessage(mConversation); mMessageUri = null; } } }存短信草稿后把对应thread_id的彩信删掉(如果存在),存彩信时也一样。
存短信的具体代码如下(按理说不应该存在thread_id=0的数据):(测试mMessageUri == null,新建下方法不被调用,另一种情况应该是打开草稿的情况)
private void updateDraftSmsMessage(final Conversation conv, String contents) { final long threadId = conv.getThreadId(); if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { LogTag.debug("updateDraftSmsMessage tid=%d, contents=\"%s\"", threadId, contents); } // If we don't have a valid thread, there's nothing to do. if (threadId <= 0) { return; } ContentValues values = new ContentValues(3); values.put(Sms.THREAD_ID, threadId); values.put(Sms.BODY, contents); values.put(Sms.TYPE, Sms.MESSAGE_TYPE_DRAFT); SqliteWrapper.insert(mActivity, mContentResolver, Sms.CONTENT_URI, values); asyncDeleteDraftMmsMessage(conv); mMessageUri = null; }存彩信使用framework里面类存储的,先获取uri,再存储。
private static void updateDraftMmsMessage(Uri uri, PduPersister persister, SlideshowModel slideshow, SendReq sendReq, HashMap<Uri, InputStream> preOpenedFiles) { if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { LogTag.debug("updateDraftMmsMessage uri=%s", uri); } if (uri == null) { Log.e(TAG, "updateDraftMmsMessage null uri"); return; } persister.updateHeaders(uri, sendReq); final PduBody pb = slideshow.toPduBody(); try { persister.updateParts(uri, pb, preOpenedFiles); } catch (MmsException e) { Log.e(TAG, "updateDraftMmsMessage: cannot update message " + uri); } slideshow.sync(pb); }
2、加载(WorkingMessage、DraftCache、Conversation)
在Activity的onStart方法及ListView的size变化时都会调用loadMessagesAndDraft()方法,这个方法会调用loadMessageContent()方法加载数据库里的短彩信。接着调用loadDraft()方法加载草稿箱。通过WorkingMessage.loadDraft方法查询草稿箱。在WorkingMessage的loadDraft方法里用异步线程查询,调用readDraftSmsMessage(Conversation conv)方法,此方法里做了限制,如果要查询的thread_id<=0或者!conv.hasDraft()则不查询返回
long thread_id = conv.getThreadId(); if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { Log.d(TAG, "readDraftSmsMessage conv: " + conv); } // If it's an invalid thread or we know there's no draft, don't bother. if (thread_id <= 0 || !conv.hasDraft()) { return ""; } Uri thread_uri = ContentUris.withAppendedId(Sms.Conversations.CONTENT_URI, thread_id); String body = ""; Cursor c = SqliteWrapper.query(mActivity, mContentResolver, thread_uri, SMS_BODY_PROJECTION, SMS_DRAFT_WHERE, null, null);如果查询到了短信,则删掉数据库的这条草稿记录再返回结果,彩信不删除
Cursor c = SqliteWrapper.query(mActivity, mContentResolver, thread_uri, SMS_BODY_PROJECTION, SMS_DRAFT_WHERE, null, null); boolean haveDraft = false; if (c != null) { try { if (c.moveToFirst()) { body = c.getString(SMS_BODY_INDEX); haveDraft = true; } } finally { c.close(); } } // We found a draft, and if there are no messages in the conversation, // that means we deleted the thread, too. Must reset the thread id // so we'll eventually create a new thread. if (haveDraft && conv.getMessageCount() == 0) { asyncDeleteDraftSmsMessage(conv); // Clean out drafts for this thread -- if the recipient set changes, // we will lose track of the original draft and be unable to delete // it later. The message will be re-saved if necessary upon exit of // the activity. clearConversation(conv, true); } if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) { LogTag.debug("readDraftSmsMessage haveDraft: ", !TextUtils.isEmpty(body)); } return body;
总结:很明显,如果conv.hasDraft()为false是得不到草稿信息的,Conversation的hasDraft方法实际调用DraftCache.getInstance().hasDraft(mThreadId),而DraftCache的hasDraft则是判断这个thread_id有没有在里面的HashSet中记录。
疑问:DraftCache什么时候得到草稿箱的thread_id?
在程序初始化时,在MmsApp的onCreate中调用了DraftCache.init()方法,此方法中构造了单例DraftCache对象,构造时调用refresh()方法,再里面调用rebuildCache()方法获取数据库内所有有草稿的thread_id给静态Hashset对象mDraftSet。在保存、
注意:当离开短信界面时onStop方法里调用的saveDraft(boolean isStopping)方法里
if (mWorkingMessage.isDiscarded()) { return; } if (!mWaitingForSubActivity && !mWorkingMessage.isWorthSaving() && (!isRecipientsEditorVisible() || recipientCount() == 0)) { if (LogTag.VERBOSE || Log.isLoggable(LogTag.APP, Log.VERBOSE)) { log("not worth saving, discard WorkingMessage and bail"); } mWorkingMessage.discard(); return; } mWorkingMessage.saveDraft(isStopping);也就是说不存储则舍弃,而在discard()方法里调用 clearConversation(mConversation, true), clearConversation方法里调用conv.setDraftState(false);一直调用到DraftCache中
synchronized (mDraftSetLock) { if (hasDraft) { changed = mDraftSet.add(threadId); } else { changed = mDraftSet.remove(threadId); } }
相关文章推荐
- NYOJ 会场安排问题
- 通过JDBC 连接MySQL问题
- JAVA开发环境配置
- 树结点,与度=边
- python ipython notebook教程
- 欢迎使用CSDN-markdown编辑器
- Ubuntu装完之后要……_(:з」∠)_
- 课后作业1
- [转载] Java字符串格式化
- SMS注册与接收短信
- POJ3630 Phone List 题解&代码
- ZOJ Paint the Grid Reloaded
- [HDU 2896] - 病毒侵袭 ac 自动机
- 一次多进程的小尝试
- hadoop搭建完毕后启动hadoop弹出ssh警告提示的解决办法
- ser2net和socat
- python入门
- 关于学科的疑惑
- [BZOJ1036][ZJOI2008]树的统计Count(树链剖分)
- IOS 将数组转化成NSData数据进行保存