|
說明:前面消息的基本知識主要參考《Series60應(yīng)用程序開發(fā)》中的有關(guān)內(nèi)容,后面是前段做MTM開發(fā)中用到的代碼。
一、消息存儲基本知識 Symbian OS提供的消息傳送架構(gòu)基于Client/Server機制,服務(wù)器負責(zé)管理手機上的各種消息,在進行消息相關(guān)操作之前我們需要了解Symbian OS是如何組織和存儲消息的。 手機中的各種消息都是以數(shù)據(jù)項(Entry)形式供程序操作,數(shù)據(jù)項有4種類型,SymbianOS為每種數(shù)據(jù)項提供了相應(yīng)的常量標(biāo)識UID,這些UID保存在msvuids.h文件中: Ø 文件夾類型,,對應(yīng)常量UID為KUidMsvFolderEntry,和PC上的文件系統(tǒng)一樣,每個文件夾可以包含其它數(shù)據(jù)項也可能是其它數(shù)據(jù)項的子數(shù)據(jù)項。 Ø 消息類型,對應(yīng)常量UID為KUidMsvMessageEntry,它表示該數(shù)據(jù)項是一條消息。 Ø 附件類型,對應(yīng)常量UID為KUidMsvAttachmentEntry,它表示該數(shù)據(jù)項是某條信息的附件。 Ø 服務(wù)類型,對應(yīng)常量UID為KUidMsvServiceEntry,服務(wù)數(shù)據(jù)項包含某個消息服務(wù)的配置信息,在一般情況還擁有通過該服務(wù)收發(fā)的消息數(shù)據(jù)項。 除了上面提到的四種類型UID還有常用到的UID是KUidMsvRootEntry(msvids.h),它指的是根數(shù)據(jù)項,根數(shù)據(jù)項包含了4個標(biāo)準(zhǔn)文件夾數(shù)據(jù)項,分別是收件箱(KMsvGlobalInBoxIndexEntryId)、發(fā)件箱(KMsvGlobalOutBoxIndexEntryId)、草稿箱(KMsvDraftEntryId)和已發(fā)送項(KMsvSentEntryId),另外根數(shù)據(jù)項下面還包含有各種消息服務(wù)的服務(wù)項,Symbian OS中消息存儲如下圖所示:
CMsvSession
CMsvSession表示客戶端與消息服務(wù)器的會話,會用到它獲得下面將要提到的CMsvEntry上下文對象。
TMsvId
它只是一個TInt32的typedef,消息服務(wù)器為每個數(shù)據(jù)項分配一個惟一的數(shù)值做為標(biāo)識,除了上面提到的幾個固定的標(biāo)識,其它的標(biāo)識都是動態(tài)分配的。想要對某個消息進行操作必須先得到它的ID,Symbian中消息相關(guān)的大部分函數(shù)都會用到TMsvId。
TMsvEntry
上面已經(jīng)提到過了它表示數(shù)據(jù)項的索引,只包含消息的一些概要信息,主要會用到Id()成員函數(shù)得到數(shù)據(jù)項的標(biāo)識ID和公有數(shù)據(jù)成員iDetails、iDescription和iDate,前面兩個成員可以用來獲取和設(shè)置索引的概要信息,iDate成員可以獲取和設(shè)置數(shù)據(jù)項的日期及時間。
CMsvEntry和CMsvServerEntry
CMsvEntry和CMsvServerEntry可以理解為數(shù)據(jù)項的上下文(Context),這兩個類非常類似,只不過CMsvEntry用于客戶端,CMsvServerEntry用于實現(xiàn)消息的服務(wù)器端,它提供了操作數(shù)據(jù)項的各種接口,可以根據(jù)指定ID定位數(shù)據(jù)項、獲得消息存儲和消息索引。
CMsvStore
上面已經(jīng)提到過它表示數(shù)據(jù)項的存儲,可以通過CMsvEntry(CMsvServerEntry)的 EditStoreL(),ReadStoreL()函數(shù)取得可編輯存儲或只讀存儲。
CMsvEntrySelection
CMsvEntrySelection是一個可以存儲TMsvId的數(shù)組,在使用CMsvEntry(CMsvServerEntry)的許多操作中都會做為參數(shù)或者返回對象。
二、數(shù)據(jù)項常用操作
下面的消息操作使用了一個CMsvEntry或 CMsvServerEntry的指針對象,這兩個類提供的功能基本一樣,但有一部分函數(shù)名會不一樣,可以查一下SDK。
1. 獲得當(dāng)前數(shù)據(jù)項索引和ID
TMsvEntry oldEntry = iServerEntry->Entry();
TMsvId oldContext = oldEntry.Id(); //如果使用CMsvEntry可以直接使用EntryId()
2. 定位到指定數(shù)據(jù)項
在更換當(dāng)前數(shù)據(jù)項之前通常先保存當(dāng)前數(shù)據(jù)項索引ID,更換數(shù)據(jù)項并完成相關(guān)操作后再更換回原來的數(shù)據(jù)項,這可以避免影響其它函數(shù),是一個很好的習(xí)慣。
TMsvId oldContext = iServerEntry->Entry().Id();
//使用SetEntry()更換當(dāng)前數(shù)據(jù)項到root
iServerEntry->SetEntry(KMsvRootIndexEntryId);
//具體操作后更換回原來數(shù)據(jù)項
iServerEntry->SetEntry(oldContext);
3. 查找數(shù)據(jù)項
下面的三個CMsvEntry成員函數(shù)都能完成在當(dāng)前數(shù)據(jù)項下進行查找的功能:
CMsvEntrySelection* ChildrenWithMtmL(TUid aMtm) const;
根據(jù)消息服務(wù)(MTM)進行查找,查找消息索引對象(TMsvEntry)的成員iMtm等于aMtm的數(shù)據(jù)項ID。
CMsvEntrySelection* ChildrenWithServiceL(TMsvId aId) const;
根據(jù)消息服務(wù)ID進行查找,查找消息索引對象(TMsvEntry)的成員iServiceId等于aId的數(shù)據(jù)項ID。
CMsvEntrySelection* ChildrenWithTypeL(TUid aEntryType) const; 根據(jù)數(shù)據(jù)項類型進行查找,查找消息索引對角的(TMsvEntry)的成員iType等于aEntryType的數(shù)據(jù)項ID。
CMsvServerEntry與之相對應(yīng)的三個函數(shù)為GetChildrenWithMtm(), GetChildrenWithService(), GetChildrenWithType(),注意的一點是CMsvEntry的三個函數(shù)都返回一個CMsvEntrySelection對象的指針,使用完之后我們要負責(zé)釋放,使用CMsvServerEntry的三個函數(shù)需要事先構(gòu)造一個CMsvEntrySelection對象,用完之后也需要釋放。
找出POP3郵箱個數(shù)的代碼
iMsvEntry->SetEntryL( KUidMsgTypePop3 );
CMsvEntrySelection* sel = NULL;
sel = entry->ChildrenWithMtmL( KPkiSmtpTechnologyTypeUid );
TInt cnt = sel->Count(); //獲得集合中數(shù)據(jù)項的個數(shù)
delete sel;
4. 更改消息索引
TMsvEntry entry = iMsvEntry->Entry();
entry.iDetails.Set( _L( “New details” ) );
iMsvEntry->ChangeL( entry ); //把更改后的數(shù)據(jù)項索引寫回消息索引中去
5. 數(shù)據(jù)項的讀寫
在進行數(shù)據(jù)項的讀寫之前需要使用EditStoreL(),ReadStoreL()函數(shù)得到相應(yīng)的存儲CMsvStore通過它提供的接口進行操作。
void CMessageView::ViewMessageL(TMsvId aId)
{
// Construct the CMsvEntry
CMsvEntry* entry = iSession->GetEntryL(aId);
CleanupStack::PushL(entry);
// Get the messaging store
CMsvStore* store = entry->ReadStoreL();
CleanupStack::PushL(store);
// Construct the CRichText and restore the body text
CParaFormatLayer* paraLayer = CParaFormatLayer::NewL();
CleanupStack::PushL(paraLayer);
CCharFormatLayer* charLayer = CCharFormatLayer::NewL();
CleanupStack::PushL(charLayer);
CRichText* body = CRichText::NewL(paraLayer, charLayer);
CleanupStack::PushL(body);
store->RestoreBodyTextL(*body);
// Extract body text from CRichText
TInt len = body->DocumentLength(); //get length
HBufC *buf = HBufC::NewL( len );
TPtr ptrBuf = buf->Des();
body->Extract( ptrBuf, 0, len ); //get data
//因為不同的消息的存儲格式不同,還可能需要對ptrBuf進行相應(yīng)的解碼才能正常
//顯示
delete buf;
buf = NULL;
CleanupStack::PopAndDestroy(5, entry);
}
|
|
|