Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Symbian OS中的消息存储与常用操作

From Wiki
Jump to: navigation, search
Article Metadata

文章
beover1984 在 29 Jul 2007 创建
最后由 hamishwillee 在 15 Dec 2011 编辑

说明:前面消息的基本知识主要参考《Series60应用程序开发》中的有关内容,后面是前段做MTM开发中用到的代码。

一、消息存储基本知识

Symbian OS提供的消息传送架构基于Client/Server机制,服务器负责管理手机上的各种消息,在进行消息相关操作之前我们需要了解Symbian OS是如何组织和存储消息的。

手机中的各种消息都是以数据项(Entry)形式供程序操作,数据项有4种类型,SymbianOS为每种数据项提供了相应的常量标识UID,这些UID保存在msvuids.h文件中:

Ø 文件夹类型,,对应常量UID为KUidMsvFolderEntry,和PC上的文件系统一样,每个文件夹可以包含其它数据项也可能是其它数据项的子数据项。

Ø 消息类型,对应常量UID为KUidMsvMessageEntry,它表示该数据项是一条消息。

Ø 附件类型,对应常量UID为KUidMsvAttachmentEntry,它表示该数据项是某条信息的附件。

Ø 服务类型,对应常量UID为KUidMsvServiceEntry,服务数据项包含某个消息服务的配置信息,在一般情况还拥有通过该服务收发的消息数据项。

除了上面提到的四种类型UID还有常用到的UID是KUidMsvRootEntry(msvids.h),它指的是根数据项,根数据项包含了4个标准文件夹数据项,分别是收件箱(KMsvGlobalInBoxIndexEntryId)、发件箱(KMsvGlobalOutBoxIndexEntryId)、草稿箱(KMsvDraftEntryId)和已发送项(KMsvSentEntryId),另外根数据项下面还包含有各种消息服务的服务项,Symbian OS中消息存储如下图所示:

Symbian OS中的消息服务器负责保存各种类型的数据项,这里有两个基本概念需要了解:消息存储和消息索引。消息存储保存了数据项的数据,保存的数据格式取决于消息服务,服务数据项使用消息存储保存服务配置信息,文件夹数据项不使用消息存储,Symbian 提供了CMsvStore类来访问数据项的消息存储;为了节省内存和快速检索消息,消息服务器把数据项的一些概要信息(标题,日期,类型,ID等)写到消息索引中,当消息服务器启动时将索引装载到RAM中直到消息服务器关闭,Symbian提供了TMsvEntry类表示数据项的索引。

操作消息常用的类和数据类型:

CMsvSession

CMsvSession表示客户端与消息服务器的会话,会用到它获得下面将要提到的CMsvEntry上下文对象。

TMsvId

它只是一个TInt32的typedef,消息服务器为每个数据项分配一个惟一的数值做为标识,除了上面提到的几个固定的标识,其它的标识都是动态分配的。想要对某个消息进行操作必须先得到它的ID,Symbian中消息相关的大部分函数都会用到TMsvId。

TMsvEntry

上面已经提到过了它表示数据项的索引,只包含消息的一些概要信息,主要会用到Id()成员函数得到数据项的标识ID和公有数据成员iDetails、iDescription和iDate,前面两个成员可以用来获取和设置索引的概要信息,iDate成员可以获取和设置数据项的日期及时间。

CMsvEntry和CMsvServerEntry

CMsvEntry和CMsvServerEntry可以理解为数据项的上下文(Context),这两个类非常类似,只不过CMsvEntry用于客户端,CMsvServerEntry用于实现消息的服务器端,它提供了操作数据项的各种接口,可以根据指定ID定位数据项、获得消息存储和消息索引。

CMsvStore

上面已经提到过它表示数据项的存储,可以通过CMsvEntry(CMsvServerEntry)的 EditStoreL(),ReadStoreL()函数取得可编辑存储或只读存储。

CMsvEntrySelection

CMsvEntrySelection是一个可以存储TMsvId的数组,在使用CMsvEntry(CMsvServerEntry)的许多操作中都会做为参数或者返回对象。

二、数据项常用操作

下面的消息操作使用了一个CMsvEntry或 CMsvServerEntry的指针对象,这两个类提供的功能基本一样,但有一部分函数名会不一样,可以查一下SDK。

1. 获得当前数据项索引和ID

TMsvEntry oldEntry = iServerEntry->Entry();
 
TMsvId oldContext = oldEntry.Id(); //如果使用CMsvEntry可以直接使用EntryId()

2. 定位到指定数据项

在更换当前数据项之前通常先保存当前数据项索引ID,更换数据项并完成相关操作后再更换回原来的数据项,这可以避免影响其它函数,是一个很好的习惯。

TMsvId oldContext = iServerEntry->Entry().Id();
//使用SetEntry()更换当前数据项到root
iServerEntry->SetEntry(KMsvRootIndexEntryId);
//具体操作后更换回原来数据项
iServerEntry->SetEntry(oldContext);

3. 查找数据项 下面的三个CMsvEntry成员函数都能完成在当前数据项下进行查找的功能:

CMsvEntrySelection* ChildrenWithMtmL(TUid aMtm) const;

根据消息服务(MTM)进行查找,查找消息索引对象(TMsvEntry)的成员iMtm等于aMtm的数据项ID。

CMsvEntrySelection* ChildrenWithServiceL(TMsvId aId) const;

根据消息服务ID进行查找,查找消息索引对象(TMsvEntry)的成员iServiceId等于aId的数据项ID。

CMsvEntrySelection* ChildrenWithTypeL(TUid aEntryType) const;

根据数据项类型进行查找,查找消息索引对角的(TMsvEntry)的成员iType等于aEntryType的数据项ID。 CMsvServerEntry与之相对应的三个函数为GetChildrenWithMtm(), GetChildrenWithService(), GetChildrenWithType(),注意的一点是CMsvEntry的三个函数都返回一个CMsvEntrySelection对象的指针,使用完之后我们要负责释放,使用CMsvServerEntry的三个函数需要事先构造一个CMsvEntrySelection对象,用完之后也需要释放。

找出POP3邮箱个数的代码

iMsvEntry->SetEntryL( KUidMsgTypePop3 );
 
CMsvEntrySelection* sel = NULL;
 
sel = entry->ChildrenWithMtmL( KPkiSmtpTechnologyTypeUid );
 
TInt cnt = sel->Count(); //获得集合中数据项的个数
 
delete sel;

4. 更改消息索引

TMsvEntry entry = iMsvEntry->Entry();
 
entry.iDetails.Set( _L( “New details” ) );
 
iMsvEntry->ChangeL( entry ); //把更改后的数据项索引写回消息索引中去

5. 数据项的读写

在进行数据项的读写之前需要使用EditStoreL(),ReadStoreL()函数得到相应的存储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进行相应的解码才能正常显示
 
delete buf;
 
buf = NULL;
 
CleanupStack::PopAndDestroy(5, entry);
 
}
This page was last modified on 15 December 2011, at 10:11.
258 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×