Symbian 通讯录(转)

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通讯录模型(Contacts Model)来实现。通讯录模型由通讯录数据库、通讯录条目(项)和通信录域三者组成,他们之间的关系是:一个手机除了系统自带的默认通讯录数据库外还可以带多个通讯录数据库;一个通讯录数据库有多个通讯录条目组成,这里每个条目就是每个联系人,具体数量限制各个手机应该不一样;而一个通讯录条目又有多个通讯录域组成,好比有姓名、工作手机号码、家庭手机号码等等,每个项就是一个域。
在这里Symbian为了统一通讯录格式,所以将通讯录条目采用vCard格式MIME规范(RFC 1521)所定义的明码文本来定义域。

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);

例2 创建数据库
CContactDatabase::CreateL()、CContactDatabase::ReplaceL()。CContactDatabase::CreateL()与

CContactDatabase::ReplaceL()函数之间的唯一差别就是:如果该数据库已经存在,前者会以KErrAlreadyExists退出。如前所述,如果没有定义参数,这些函数将创建一个默认的数据库。

TFileName contactDbFilePath(_L("C:\\system\\data\\Contacts.cdb"));
CContactDatabase* newDefaultContactDb;
if (CContactDatabase::FindContactFile(contactDbFilePath))
newDefaultContactDb = CContactDatabase::ReplaceL();
else
newDefaultContactDb = CContactDatabase::CreateL();
CleanupStack::PushL(newDefaultContactDb);
CleanupStack::PopAndDestroy(newDefaultContactDb);

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

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

CContactDatabase* contactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactsDb);
TContactIter iter(*contactsDb);
TContactItemId cardId;
while ((cardId = iter.NextL()) != KNullContactId)
{
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(KSurname,"Wilkinson");
_LIT(KWorkPhone,"+441617779700");

CContactDatabase* contactDb = CContactDatabase::OpenL();
CleanupStack::PushL(contactDb);

CContactItem* contact = CContactCard::NewLC();

CContactItemField* field = CContactItemField::NewLC(
KStorageTypeText, KUidContactFieldFamilyName);
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();

contactDb->AddNewContactL(*contact);
contactDb->SetOwnCardL(*contact);
CleanupStack::PopAndDestroy(2);

例5 查找并更新通讯录条目

这个例子比较复杂,涉及的查找函数为FindAsyncL,该类函数实例有:
CContactIdArray * CContactDatabase::FindLC(const TDesC &aText, const CContactItemFieldDef *aFieldDef);
CIdleFinder * CContactDatabase::FindAsyncL(const TDesC &aText, const CContactItemFieldDef *aFieldDef, MIdleFindObserver *aObserver);
还有对应的FindInTextDefLC()和FindInTextDefAsyncL()各两组,具体参见sdk。

CContactDatabase* iContactsDb = CContactDatabase::OpenL();
CleanupStack::PushL(iContactsDb);
CContactItemFieldDef* iFieldDef =
new (ELeave) CContactItemFieldDef();
CleanupStack::PushL(iFieldDef);
iFieldDef->AppendL(KUidContactFieldGivenName);
iFieldDef->AppendL(KUidContactFieldFamilyName);
_LIT(KFindToken, "Bond");
_LIT(KOtherForename, "Wilkinson");
CIdleFinder* iFinder = iContactsDb->FindAsyncL(KFindToken,
iFieldDef, this);
CleanupStack::PushL(iFinder);
if(iFinder->IsComplete())
{
if(iFinder->Error() == KErrNone)
{
CContactIdArray* result = iFinder->TakeContactIds();
CleanupStack::PushL(result);
for (TInt i = 0; i < result->Count(); i++)
{
TContactItemId cardId = (*result)[i];
CContactItem* ownCard = iContactsDb ->OpenContactL(cardId);
CleanupStack::PushL(ownCard);
TInt index = ownCard->CardFields().Find(KUidContactFieldGivenName);
ownCard->CardFields()[index].TextStorage()->SetTextL(KOtherForename);
iContactsDb ->CommitContactL(*ownCard);
CleanupStack::PopAndDestroy(); // ownCard
}
CleanupStack::PopAndDestroy(); //result;
}
}
CleanupStack::PopAndDestroy(3);// iContactsDb、iFieldDef、iFinder

posted @ 2010-08-07 15:56  冰岛  阅读(766)  评论(0编辑  收藏  举报