<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->
#ifndef _CONTACTHAND_H_
#define _CONTACTHAND_H_
#include <cntdb.h> //CContactDatabace
#include <cntitem.h>
#include <cntfield.h>
#include <cntdef.h> //TContactItemId ******typedef TInt32 TContactItemId;
#include <cntfldst.h>
#include <e32base.h>
class CContactHand : public CBase
{
public :
static CContactHand * NewL ();
static TInt ParseWord ( TAny *); // 需要再次学习
~CContactHand ();
void AddEmployerL ( TContactItemId aCntId, const TDesC & aCompany); // 写入 公司 属性到名片
CDesCArray * ReadTextFieldL ( TContactItemId aCntId, TFieldType aType); // 读取
void AddCardL ( const TDesC & aFirstName, const TDesC & aLastName, const TDesC & aPhone); // 写入名片信息
void RemoveContactL ( TContactItemId aCntId); // 删除
CContactIdArray * FindWithCallbackLC ( TFieldType aField, const TDesC & aMatch); // 通过关键字查找
void MoveContactL ( TContactItemId aCntId, const TDesC & aNewGroup);
private :
void ConstructL ();
CContactHand ();
private :
TCallBack iCallback ;
CContactDatabase * iCntDb ;
};
#endif
#include "contacthand.h"
#include <e32std.h>
void CContactHand::ConstructL ()
{
/*
* 手机上一般有一个默认的名片数据库
* 但是我们在处理名片的时候一定要记住假设这个数据库是不存在的
* 这样做防止特殊的情况使程序崩溃
*/
TRAPD (error, iCntDb = CContactDatabase :: OpenL ()); // 打开数据库 用宏查错
if (KErrNotFound)
iCntDb = CContactDatabase :: CreateL (); // 没有找到就创建一个数据库
else
User :: LeaveIfError (error);
}
CContactHand::CContactHand (): iCallback (& CContactHand ::ParseWord ) // 不明白这个在做什么
{}
/*
* 下面的函数只是添加了名片的一项记录,可以修改参数得到完整的记录,
* 或则自己解析参数的意义,得到完整名片
*/
void CContactHand::AddEmployerL ( TContactItemId aCntId, const TDesC & aCompany)
{
// 打开这个 ID 的名片,并且 Lock 这个名片防止修改 这里名片已经存在
CContactItem * item = iCntDb -> OpenContactLX (aCntId);
CleanupStack :: PushL (item);
//make a company name field to add to the contact 用一个域来添加名片中的项
CContactItemField * field = CContactItemField :: NewLC ( KStorageTypeText );
field-> AddFieldTypeL (KUidContactFieldCompanyName);
field-> TextStorage ()-> SetTextL (aCompany); // 把记录添加到 Field
item-> AddFieldL (*field); // 把 field 加到 item
CleanupStack :: PopAndDestroy (field);
iCntDb -> CommitContactL (*item); // 把记录提交
CleanupStack :: PopAndDestroy (item);
CleanupStack :: PopAndDestroy (); // 释放 Item 的锁
}
/*
* 参数 名片 ID 数据类型
* 返回 名片所有内容
* 描述 读取名片所有 Field
*/
CDesCArray * CContactHand::ReadTextFieldL ( TContactItemId aCntId, TFieldType aType)
{
// 创建描述数组,存储记录
CDesCArray * result = new ( ELeave ) CDesCArrayFlat (2); // 这个 New 比较奇怪
CleanupStack :: PushL (result);
// 用数据库引擎读取记录,关心我们感兴趣的部分, EIncludeFields 接受特殊的部分 EMaskHiddenFields 不接受隐藏
CContactItemViewDef * viewDef = CContactItemViewDef :: NewL ( CContactItemViewDef :: EIncludeFields ,
CContactItemViewDef :: EMaskHiddenFields );
viewDef-> AddL (aType); // 不知道语句在做什么
//get the contact item
CContactItem * item = iCntDb -> ReadContactLC (aCntId,*viewDef);
//get all the fields
CContactItemFieldSet & fieldSet = item-> CardFields ();
// 循环获取信息
for ( TInt i = 0; i < fieldSet. Count (); i++)
{
CContactItemField & field = fieldSet[i];
if ( KStorageTypeText == field. StorageType ())
{
const TPtrC value = field. TextStorage ()-> Text ();
result-> AppendL (value);
}
}
CleanupStack :: PopAndDestroy (2,viewDef); // 对象使用 NewLC 或者 LC 结尾的函数创建的对象都会在 Stack 中留下指针
CleanupStack :: Pop (result);
return result;
}
/*
* 参数 名片的 Fiel 的内容
* 描述 新建一张名片,并写入相应的内容到相应的 Field
*/
void CContactHand::AddCardL ( const TDesC & aFirstName, const TDesC & aLastName, const TDesC & aPhone)
{
// 创建一个名片
CContactCard * contactCard = CContactCard :: NewLC (); // 注意在栈中留有指针
// 添加入 firstName
CContactItemField * firstName = CContactItemField :: NewLC ( KStorageTypeText );
firstName-> AddFieldTypeL (KUidContactFieldGivenName);
firstName-> TextStorage ()-> SetTextL (aFirstName); // 数据写入
contactCard-> AddFieldL (*firstName);
CleanupStack :: Pop (firstName);
// 添加入 lastName
CContactItemField * lastName = CContactItemField :: NewLC ( KStorageTypeText );
lastName-> AddFieldTypeL (KUidContactFieldFamilyName);
lastName-> TextStorage ()-> SetTextL (aLastName); // 数据写入
contactCard-> AddFieldL (*lastName);
CleanupStack :: Pop (lastName);
// 添加入 lastName
CContactItemField * phone = CContactItemField :: NewLC ( KStorageTypeText );
phone-> AddFieldTypeL (KUidContactFieldPhoneNumber);
phone-> TextStorage ()-> SetTextL (aPhone); // 数据写入
contactCard-> AddFieldL (*phone);
CleanupStack :: Pop (phone);
// 名片添加到 DB
iCntDb -> AddNewContactL (*contactCard); // 参数是 CContactItem 可见 Item 同 Card
CleanupStack :: PopAndDestroy (contactCard);
}
/*
* 参数 关键字字段 关键字值
* 描述 查找和关键字匹配的结果
* 高手支招 ******** 大数据库查找可能需要很多时间,可调用异步函数 CContactDatabase::FindInTextDefAsyncL()
* ***************** 如果结果过大,可以使用相对较小的批处理来获取(比如利用 Clidle )
*/
CContactIdArray * CContactHand::FindWithCallbackLC ( TFieldType aField, const TDesC & aMatch)
{
// 搜索关键字属于什么字段,需要建立数组
TContactTextDefItem field(aField);
CContactTextDef * textDef = CContactTextDef :: NewL ();
CleanupStack :: PushL (textDef);
textDef->AppendL(field);
// 一个描述数组来设置搜索
CDesCArray * match = new ( ELeave ) CDesCArrayFlat (1);
CleanupStack :: PushL (match);
match-> AppendL (aMatch);
CContactIdArray * result = iCntDb -> FindInTextDefLC (*match,textDef, iCallback ); // 查找
CleanupStack :: Pop (result);
CleanupStack :: Pop (2,textDef); //textDef match
return result;
}
/*
* 非常不明白这个函数在干什么
*/
TInt CContactHand::ParseWord ( TAny * aParam)
{
SFindInTextDefWordParser * parserStruct = ( SFindInTextDefWordParser *)aParam; // 强制转换 SFindInTextDefWordParser*
TPtrC searchString(*(parserStruct-> iSearchString ));
TInt index = KErrNotFound;
TInt error = KErrNone;
while (0 <= (index = searchString. Locate ( ' ' )))
{
if (index > 0)
{
TRAP (error,parserStruct-> iWordArray -> AppendL (searchString. Left (index))); // 这个在检查什么错误
if (error != KErrNone)
return error;
if (searchString. Length () > index + 1)
searchString. Set (searchString. Mid (index));
else
{
searchString. Set (KNullDesC); //_LIT(KNullDesC,"");
break ;
}
}
else
searchString. Set (searchString. Mid (1)); //remove first character as it is a space
}
if (searchString. Length () > 0) //the last word
{
TRAP (error,parserStruct-> iWordArray -> AppendL (searchString)); // 这个在检查什么错误
if (error != KErrNone)
return error;
}
return KErrNone;
}
/*
* 参数 名片的 ID 添加到的组名称
* 描述 通过组名得到组的 ID (不存在则新建)并加入 ID 的名片
* 高手支招 ********* 会遇到非原子操作问题:函数执行一半,失败了;需要考虑一种方法让其回滚
*/
void CContactHand::MoveContactL ( TContactItemId aCntId, const TDesC & aNewGroup)
{
CContactItem * item = iCntDb -> OpenContactLX (aCntId);
CleanupStack :: PushL (item);
// 找到名片属于的组
TContactItemId groupId = KNullContactId; // 记录组的 ID
CContactItem * group = NULL ;
if (KUidContactCard == item. Type ())
{
CContactCard * card = ( CContactCard *)item;
// Returns a pointer to a list of contact item IDs which identify the groups to which this
// contact card belongs
CContactIdArray * ids = card-> GroupsJoinedLC ();
// 个数大于 0 就把第一个数据赋值
if (0 < ids-> Count ())
groupId = (*ids)[0]; // 这样的操作可以学习 和 C 类似 这里如果 Count()>1 可以循环
CleanupStack :: PopAndDestroy (ids);
}
if (KNullContactId != groupId)
{
group = iCntDb -> OpenContactLX (groupId);
CleanupStack :: PushL (group);
iCntDb -> RemoveContactFromGroupL (*item,*group);
CleanupStack :: Pop (group);
CleanupStack :: Pop (); // 解除 group 的锁
group = NULL ;
}
CleanupStack :: Pop (2); //item , 解除 Item 的锁 ?对于 Pop 的用法还是不很清楚
// 查找新的组 没有就新建一个
groupId = KNullContactId;
CContactIdArray * groupArrayId = iCntDb -> GetGroupIdListL ();
if ( NULL != groupArrayId )
{
CleanupStack :: PushL (groupArrayId );
for ( TInt i = 0; i < groupArrayId . Count (); i++)
{
group = iCntDb -> ReadContactLC ((*groupArrayId )[i]);
TPtrC lable = (( CContactGroup *)group)-> GetGroupLabelL ();
if (aNewGroup. MatchC (lable))
{
groupId = (*groupArrayId )[i];
i = groupArrayId . Count (); // 相当于 Break 这样做有什么好处
}
CleanupStack :: PopAndDestroy (group);
group = NULL ;
}
CleanupStack :: PopAndDestroy (groupArrayId );
}
if (groupId == KNullContactId) // 没有找到相应的组 新建
{
group = iCntDb -> CreateContactGroupLC (aNewGroup); // 在栈中留下变量
groupId = group-> Id ();
CleanupStack :: PopAndDestroy (group);
}
iCntDb -> AddContactToGroupL (aCntId,groupId); // 把名片 Id 对应的 Item 添加到 groupId 对应的组
}
/*
* 参数 名片的 ID
* 描述 删除 ID 位置的名片
* 改进 函数没有判断没有找到需要删除的名片 也没有返回删除与否
* 高手支招 ******** 在删除名片后调用 CContactDatabase::CompactL() 可以减小数据库大小,但是不用每次调用
* ***************** 一般删除几次调整下比较好
*/
void CContactHand::RemoveContactL ( TContactItemId aCntId)
{
iCntDb -> DeleteContactL (aCntId);
// iCntDb->CompactL();
}
CContactHand::~CContactHand ()
{
if ( iCntDb )
delete iCntDb ;
iCntDb = NULL ;
}