注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Simon

 
 
 

日志

 
 

Symbian OS应用开发学习笔记之通讯录(电话薄Contacts)  

2010-06-16 01:27:27|  分类: Symbian C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
Symbian OS通讯录模型

Symbian OS手机的通讯录采用文件方式存储,用symbian自己的说法就是通讯录数据库。每个Symbian OS手机都有一个默认的通讯录数据库,这个通讯录数据库在2nd和3rd两个版本手机中的位置是不同的,前者是c:\ system\data\Contacts.cdb,后者是c:\private\100012a5\DBS_100065FF_Contacts.cdb。不管怎么说两者都在内部闪存中,也就是跟优盘差不多的介质,由于symbian OS的文件系统暂时还没有仔细拜读过,所以具体差别暂不知,总之掉电不会失去就是了。

Symbian OS的手机通讯录在开发上的操作依靠Symbian OS通讯录模型(Contacts Model)来实现。通讯录模型由通讯录数据库、通讯录条目(项)和通信录域三者组成,他们之间的关系是:一个手机除了系统自带的默认通讯录数据库外还可以带多个通讯录数据库;一个通讯录数据库有多个通讯录条目组成,这里每个条目就是每个联系人,具体数量限制各个手机应该不一样;而一个通讯录条目又有多个通讯录域组成,好比有姓名、工作手机号码、家庭手机号码等等,每个项就是一个域。

在这里Symbian为了统一通讯录格式,所以将通讯录条目采用vCard格式MIME规范(RFC 1521)所定义的明码文本来定义域,具体的vCard简单介绍见附录。


Symbian OS通讯录操作API类

知道了Contacts Model的概念,Symbian OS将很多系统API操作封装为几个类:

CContactDatabase(数据库类):负责新建、打开、关闭等基本数据库操作外,还负责数据库更新(通讯录条目的新建、修改、删除需要通过CContactDatabase类的操作才能实现)、排序和查找,另外还有一些建立快速拨号之类的操作也是通过它来实现。

CContactItem(通讯录条目类):由唯一的一个TContactItemId(一个TInt32类型的宏定义)标识,负责具体一个通讯录条目的创建、修改,其直接管理每一个通讯录域

CContactItemField(域类):每一个域就是一个真实单一的数据,该数据的类型具有存储类型(TStorageType)和域类型(TFieldType)同时决定,具体的四种存储类型和多种域类型定义见系统头文件cntdef.h内的定义。

当然还有很多其它的类,比如CContactItemFieldSet(域集类)、CContactFieldStorage(与存储基类)、CContactTextFields(文本存储域类)、MContactDbObserver(通讯数据库观察类)等等,涉及面太大,具体也不能凭空说清楚,代码中出现就知道了。


Symbian OS通讯录操作实例

例1、       打开和关闭数据库

CContactDatabase::OpenL()函数有两个重载函数。如果该函数没有给出一个参数,就打开默认的数据库。另一种情况是,应用软件设计师也可以传递一个有关数据库的路径和文件名,规定打开一个指定数据库。

//打开默认数据库

CContactDatabase* contactsDb = CContactDatabase::OpenL();

CleanupStack::PushL(contactsDb);

//取得当前数据库所有通讯条目数

TInt numberOfContacts = contactsDb->CountL();

//释放数据库

CleanupStack::PopAndDestroy(contactsDb);

要注意的是:某个通信录数据库并不具有Close()函数或类似的函数,否则我们压入清除栈时就得用CleanupClosePushL()函数了。

例2、       创建数据库

CContactDatabase::CreateL()函数与CContactDatabase::ReplaceL()函数之间的唯一差别就是:如果该数据库已经存在,前者会以KErrAlreadyExists退出。如前所述,如果没有定义参数,这些函数将创建一个默认的数据库。CContactDatabase::FindContactFile()函数给出了一个描述符,如果不存在默认数据库的话,该描述符就会返回该默认数据库的位置。

// If one is found, replace it with a new empty default database.

// If no default database is found, create a new one.

TFileName contactDbFilePath;

CContactDatabase* newDefaultContactDb;

//是否存在默认数据库

if(CContactDatabase::FindContactFile(contactDbFilePath))

{

newDefaultContactDb = CContactDatabase::ReplaceL();

}

else

{

newDefaultContactDb = CContactDatabase::CreateL();

}

CleanupStack::PushL(newDefaultContactDb);

// 添加自己功能代码

CleanupStack::PopAndDestroy(newDefaultContactDb);

注:以上代码负责创建一个空的默认数据库。

例3、       读取(遍历)通讯录条目

可以用TContactIter类(该类起到数据库操作中类似游标的作用)来遍历一个通信录数据库。这个类提供了一整套的函数,用于遍历所有的通信录项。所有的函数都用通信录项ID (TContactItemId) 进行操作,该ID 用于访问某个特定的通信录项。

// Open the default contacts database:

CContactDatabase* contactsDb = CContactDatabase::OpenL();

CleanupStack::PushL(contactsDb);

TContactIter iter(*contactsDb);

TContactItemId cardId;

//循环遍历

while( ( cardId = iter.NextL() ) != KNullContactId )

{

//读取相应项,这里之所以称其card,就是其实际相当于读一个完整的vCard条目

CContactItem* card = contactsDb->ReadContactL(cardId);

CleanupStack::PushL(card);

//添加自己功能代码

//……

contactsDb->CloseContactL(card->Id());

CleanupStack::PopAndDestroy(); // card

}

CleanupStack::PopAndDestroy(); // contactsDb

例4、       新建通讯录条目

// 字符串声明

_LIT(KForenameLabel,"Forename");//中文“名”

_LIT(KSurnameLabel,"Surname"); //中文“姓”

_LIT(KWorkPhoneLabel,"Work Phone");

_LIT(KForename,"Steve");

_LIT(KOtherForename,"Bob");

_LIT(KSurname,"Wilkinson");

_LIT(KWorkPhone,"+441617779700");

//以上定义的字符串,在以后例子中将直接使用,不再重新进行定义了

//打开默认数据库

CContactDatabase* contactsDb = CContactDatabase::OpenL();

CleanupStack::PushL(contactsDb);

// 建立一个新条目

CContactItem* contact = CContactCard::NewLC();

//创建一个新的文本存储类型的姓域

CContactItemField* field =

CContactItemField::NewLC(KStorageTypeText, KUidContactFieldFamilyName);

//将姓域建立与vCard的映射

field->SetMapping(KUidContactFieldVCardMapUnusedN);

//设置域标签

field->SetLabelL(KSurnameLabel);

//设置域值

field->TextStorage()->SetTextL(KSurname);

//把该域加入到新建的条目中

contact->AddFieldL(*field);    

CleanupStack::Pop();

//添加文本存储类型的名域

field=CContactItemField::NewLC(KStorageTypeText, KUidContactFieldGivenName);

field->SetMapping(KUidContactFieldVCardMapUnusedN);

field->SetLabelL(KForenameLabel);

field->TextStorage()->SetTextL(KForename);

contact->AddFieldL(*field);

CleanupStack::Pop();

//添加文本存储类型的手机号码域

field=CContactItemField::NewLC(KStorageTypeText, KUidContactFieldPhoneNumber);

field->SetMapping(KUidContactFieldVCardMapTEL);

field->SetLabelL(KWorkPhoneLabel);

field->TextStorage()->SetTextL(KWorkPhone);

contact->AddFieldL(*field);

CleanupStack::Pop();

//把建立的新记录添加到数据库中

contactsDb->AddNewContactL(*contact);

contactsDb->SetOwnCardL(*contact);

CleanupStack::PopAndDestroy(2); // contact contactsDb

  评论这张
 
阅读(424)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018