读取联系人的方法有API和数据库。这里所说的联系人有两个概念,一个是SIM卡上的,一个设备中的。
想看看如果读取SIM卡中的联系人。
#include
#pragma comment(lib,"cellcore.lib")
// CSimPhoneBookView message handlers
void ReadSimPhoneBook()
{
//Sim Card
HSIM g_hSim = NULL;
SIMCAPS g_simcaps;
const DWORD g_dwLocation = SIM_PBSTORAGE_SIM;//SIM_PBSTORAGE_OWNNUMBERS;//SIM_PBSTORAGE_SIM;
DWORD dwRecNum=0;
DWORD dwCurRec = 0;
if (FAILED(SimInitialize(SIM_INIT_NONE, NULL, 0, &g_hSim)))
return;
if (FAILED(SimGetDevCaps(g_hSim, SIM_CAPSTYPE_PBINDEXRANGE, &g_simcaps)))
return;
dwRecNum = g_simcaps.dwMaxPBIndex - g_simcaps.dwMinPBIndex+1;
dwCurRec = g_simcaps.dwMinPBIndex;
SIMPHONEBOOKENTRY simPhoneEntry;
while( dwCurRec <= dwRecNum )
{
memset(&simPhoneEntry,0,sizeof(SIMPHONEBOOKENTRY));
if(SUCCEEDED(SimReadPhonebookEntry(g_hSim, g_dwLocation, dwCurRec, &simPhoneEntry)))
{
int iItem = lstCtrl.InsertItem(lstCtrl.GetItemCount(),simPhoneEntry.lpszText);
lstCtrl.SetItemText(iItem,1,simPhoneEntry.lpszAddress);
CString tmp;
tmp.Format(_T("%ld"),dwCurRec);
lstCtrl.SetItemText(iItem,2,tmp);
}
dwCurRec++;
}
SimDeinitialize(g_hSim);
g_hSim = NULL;
}
void Add()
{
//Sim Card
HSIM g_hSim = NULL;
SIMCAPS g_simcaps;
const DWORD g_dwLocation = SIM_PBSTORAGE_SIM;//SIM_PBSTORAGE_OWNNUMBERS;//SIM_PBSTORAGE_SIM;
DWORD dwRecNum=0;
DWORD dwCurRec = 0;
if (FAILED(SimInitialize(SIM_INIT_NONE, NULL, 0, &g_hSim)))
return;
if (FAILED(SimGetDevCaps(g_hSim, SIM_CAPSTYPE_PBINDEXRANGE, &g_simcaps)))
return;
dwRecNum = g_simcaps.dwMaxPBIndex - g_simcaps.dwMinPBIndex+1;
dwCurRec = g_simcaps.dwMinPBIndex;
SIMPHONEBOOKENTRY simPhoneEntry;
simPhoneEntry.cbSize = sizeof(SIMPHONEBOOKENTRY);
simPhoneEntry.dwParams = SIM_PARAM_PBE_ALL;
simPhoneEntry.dwAddressType = SIM_ADDRTYPE_NATIONAL;
simPhoneEntry.dwNumPlan = SIM_NUMPLAN_TELEPHONE;
CString tmp;
for( dwCurRec = g_simcaps.dwMinPBIndex;dwCurRec<=dwRecNum;dwCurRec++ )
{
tmp.Format(_T("name_%ld"),dwCurRec);
wcscpy(simPhoneEntry.lpszText,tmp);
tmp.Format(_T("123456%.3ld"),dwCurRec);
wcscpy(simPhoneEntry.lpszAddress,tmp);
SimWritePhonebookEntry(g_hSim, g_dwLocation, dwCurRec, &simPhoneEntry);
}
SimDeinitialize(g_hSim);
g_hSim = NULL;
}
//下面的代码通过系统自带的数据库来读取
int CopyPhoneBook(BOOL FLAG)
{
///
//读数据库中(在内存中读写,只能用API不能用WINCE封装的类,后者只对用户自定义的数据库有用)
//存储地址本的数据库是Contacts Database,手机中看不到,加载在内存中
//
CEGUID ceguid;
TCHAR szVolName[128];
CREATE_INVALIDGUID(&ceguid);
while(::CeEnumDBVolumes(&ceguid,szVolName,MAX_PATH))
{
if(wcsnicmp(L"SystemHeap",szVolName,10)==0)
{
/将当前数据库卷定位到SystemHeap上
break;
}
}
CEOID ceoid;
ceoid = 0;
CENOTIFYREQUEST *pRequest = (CENOTIFYREQUEST *) LocalAlloc(LPTR,sizeof(CENOTIFYREQUEST));
pRequest->dwSize = sizeof(CENOTIFYREQUEST);
pRequest->hwnd = NULL;
pRequest->hHeap = NULL;
pRequest->dwFlags = CEDB_EXNOTIFICATION;
//打开联系人数据库,并注册事件
HANDLE hdDB;
hdDB = ::CeOpenDatabaseEx(&ceguid,&ceoid,L"Contacts Database",0,0,pRequest);
if(hdDB == INVALID_HANDLE_VALUE)
{
// AfxMessageBox(L"打开失败");
return 0;
}
int iCount;
CEOIDINFO oldinfo;
CEOID CEoid =0;
if(!CeOidGetInfoEx(&ceguid,ceoid,&oldinfo))
{
// AfxMessageBox(L"获取信息失败");
return 0;
}
//数据库的记录总数
iCount = oldinfo.infDatabase.wNumRecords;
if(0 == iCount)
return 0;
DWORD dwIndex;
PBYTE pBuff;
WORD wProps;
DWORD dwRecSize;
PCEPROPVAL pRecord;
for(int i = 0; i < iCount; ++i)
{
//移动记录指针
CEoid = CeSeekDatabase(hdDB,CEDB_SEEK_BEGINNING,i,&dwIndex);
//ASSERT(CEoid !=0);
pBuff = 0;
//读取所有字段值
CEoid = CeReadRecordProps(hdDB,CEDB_ALLOWREALLOC,&wProps,NULL,&(LPBYTE)pBuff,&dwRecSize);
/*
typedef enum
{
Firstname = 0x3a06001f,//姓
WorkTel = 0x3a08001f,//工作电话
HomeTel = 0x3a09001f,//住宅电话
Lastname = 0x3a11001f,//名
Company = 0x3a16001f,//公司/单位
JobTitle = 0x3a17001f,//职务
Department = 0x3a18001f,//部门
OfficeLoc = 0x3a19001f,//办公室
MobileTel= 0x3a1c001f,//移动电话
RadioTel = 0x3a1d001f,//无线电话
CarTel = 0x3a1e001f,//车载电话
WorkFax = 0x3a24001f,//工作传真
HomeFax = 0x3a25001f,//住宅传真
HomeTel2 = 0x3a2f001f ,//住宅电话2
Birthday = 0x40010040,//生日
Assistant = 0x4002001f,//助理
Anniversary = 0x40030040, //周年纪念
AssistantTel = 0x4004001f,//助理电话
Children = 0x4006001f,//子女
WorkTel2 = 0x4007001f,//工作电话2
HomePage = 0x4008001f,//主页
Pager = 0x4009001f,//寻呼机
Spouse = 0x400a001f,//配偶
Name = 0x4013001f,//姓名
Title = 0x4023001f,//称呼(对联系人)
HomeAddr = 0x4040001f,//家庭地址
HomeCity = 0x4041001f,//家庭所在城市
HomeState = 0x4042001f,//家庭所在的省/州
HomeZip = 0x4043001f,//家庭邮编
HomeCountry = 0x4044001f,//家庭所在国家
WorkAddr = 0x4045001f,//工作地址
WorkCity = 0x4046001f,//工作的城市
WorkState = 0x4047001f, //工作的省/州
WorkZip = 0x4048001f,//工作地的邮编
WorkCountry = 0x4049001f,//工作地的国家
OtherAddr = 0x404a001f,//其他地址
OtherCity = 0x404b001f,//其他城市
OtherState = 0x404c001f,//其他省/州
OtherZip = 0x404d001f,//其他邮编
OtherCountry = 0x404e001f,//其他的国家
Email = 0x4083001f,//电子邮箱
Email2nd = 0x4093001f,//电子邮箱2
Email3rd = 0x40a3001f//电子邮箱3
}Contacts_field; //Contacts Database的字段,系统定义不可更改
*/
//ASSERT(CEoid !=0);
pRecord = (PCEPROPVAL)pBuff;
LPWSTR Mobile = NULL;
LPWSTR NAME = NULL;
int Len_Mobile;
int Len_Name;
CString One;
for(int j = 0; j < wProps; ++j)
{
switch(pRecord->propid)
{
case MobileTel ://移动电话
{
Mobile = pRecord->val.lpwstr;
WCharToMByte(Mobile,Mob,sizeof(Mob)/sizeof(Mob[0]));//可将记录写入文件中
}
break;
case Name://姓名
{
NAME = pRecord->val.lpwstr;
WCharToMByte(NAME,Nam,sizeof(Nam)/sizeof(Nam[0]));//可将记录写入文件中
}
default:
break;
}
pRecord ++;
}
LocalFree(pBuff);
}
//关闭数据库
if(! CloseHandle(hdDB))
{
// MessageBox(NULL,L"关闭数据库失败",NULL,MB_OK);
return 0;
}
if(!FLAG)
f.Close();
if(!FLAG)
DeletePhoneBook();
// Sleep(1000);
return 1;
}
//
//删除联系人记录
void CCellGuardApp::DeletePhoneBook(void)
{
CEGUID ceguid;
TCHAR szVolName[128];
CREATE_INVALIDGUID(&ceguid);
while(::CeEnumDBVolumes(&ceguid,szVolName,MAX_PATH))
{
if(wcsnicmp(L"SystemHeap",szVolName,10)==0)
{
/将当前数据库卷定位到SystemHeap上
break;
}
}
CEOID ceoid;
ceoid = 0;
CENOTIFYREQUEST *pRequest = (CENOTIFYREQUEST *) LocalAlloc(LPTR,sizeof(CENOTIFYREQUEST));
pRequest->dwSize = sizeof(CENOTIFYREQUEST);
pRequest->hwnd = NULL;
pRequest->hHeap = NULL;
pRequest->dwFlags = CEDB_EXNOTIFICATION;
//打开联系人数据库,并注册事件
HANDLE hdDB;
hdDB = ::CeOpenDatabaseEx(&ceguid,&ceoid,L"Contacts Database",0,0,pRequest);
if(hdDB == INVALID_HANDLE_VALUE)
{
// MessageBox(NULL,L"打开失败",NULL,MB_OK);
return ;
}
int iCount;
CEOIDINFO oldinfo;
CEOID CEoid =0;
if(!CeOidGetInfoEx(&ceguid,ceoid,&oldinfo))
{
// MessageBox(NULL,L"获取信息失败",NULL,MB_OK);
return ;
}
//数据库的记录总数
iCount = oldinfo.infDatabase.wNumRecords;
if(0 == iCount)
return ;
CEOID oid;
DWORD dwIndex;
oid = CeSeekDatabase(hdDB, CEDB_SEEK_BEGINNING, 0, &dwIndex);
while(oid)
{
// Update GUI with currently selected record
if(!CeDeleteRecord(hdDB, oid))
{;}
oid = CeSeekDatabase(hdDB, CEDB_SEEK_CURRENT, 1, &dwIndex);
}
//关闭数据库
if(! CloseHandle(hdDB))
{
// br> return ;
}
}
// 从恢复地址本:从文件中写数据库
void CCellGuardApp::ReDoAddress(void)
{
// TODO: Add your control notification handler code here
/
// 打开数据库
/
CEGUID ceguid;
TCHAR szVolName[128];
CREATE_INVALIDGUID(&ceguid);
while(::CeEnumDBVolumes(&ceguid,szVolName,MAX_PATH))
{
if(wcsnicmp(L"SystemHeap",szVolName,10)==0)
{
/将当前数据库卷定位到SystemHeap上
break;
}
}
CEOID ceoid;
ceoid = 0;
CENOTIFYREQUEST *pRequest = (CENOTIFYREQUEST *) LocalAlloc(LPTR,sizeof(CENOTIFYREQUEST));
pRequest->dwSize = sizeof(CENOTIFYREQUEST);
pRequest->hwnd = NULL;
pRequest->hHeap = NULL;
pRequest->dwFlags = CEDB_EXNOTIFICATION;
//打开联系人数据库,并注册事件
HANDLE hdDB;
hdDB = ::CeOpenDatabaseEx(&ceguid,&ceoid,L"Contacts Database",0,0,pRequest);
if(hdDB == INVALID_HANDLE_VALUE)
{
// MessageBox(NULL,L"打开失败",NULL,MB_OK);
return;
}
///
// 打开备份地址本的文件
///
CFile f;
CFileException ex;
if (!f.Open(L"1.txt", CFile::modeRead | CFile::shareDenyWrite, &ex))
{
// complain if an error happened, no need to delete the ex object
TCHAR szError[1024];
ex.GetErrorMessage(szError, 1024);
return;
}
f.SeekToBegin();
DWORD dwLen = f.GetLength();
//如果文件长度为0,则退出函数
if(0 == dwLen)
return ;
char * buf = new char[dwLen + 1];
memset(buf, 0, dwLen);
f.Read(buf, dwLen);
f.Close();
///
// 向数据库中写数据
///
TCHAR NAME[128] = {0};
TCHAR PHONE[36] = {0};
char *Nam;
char *Phone;
char *seps = "/t/r/n";
int Count = 0;
do{
++ Count;
if(1 == Count)
Nam = strtok(buf,seps);
else
Nam = strtok(NULL,seps);
MByteToWChar(Nam,NAME,sizeof(NAME)/sizeof(NAME[0]));
Phone = strtok(NULL,seps);
MByteToWChar(Phone,PHONE,sizeof(PHONE)/sizeof(PHONE[0]));
if(Nam || Phone)
{
//写入数据库
CEPROPVAL *pProps;
pProps = new CEPROPVAL[2];
memset(pProps,0,LocalSize(pProps));
pProps->propid = MobileTel;
pProps->val.lpwstr = PHONE;
pProps ++;
pProps->propid = Name ;
pProps->val.lpwstr = NAME;
//写到文件中
pProps = pProps -1;
CEOID CEoid = CeWriteRecordProps(hdDB,0,2,pProps);
DWORD ERR = GetLastError();
if(0 == CEoid)
// MessageBox(NULL,L"写数据库操作失败!",NULL,MB_OK);
delete []pProps;
}
}while(Nam && Phone);
//关闭数据库
if(! CloseHandle(hdDB))
{
// MessageBox(NULL,L"关闭数据库失败",NULL,MB_OK);
return ;
}
}
http://www.cppblog.com/zhangyq/archive/2009/04/16/80200.aspx
我的例子能写入数据,但还是有些小问题
就是但名称为”一个“的时候,写入不成功,其他都是可以的,一起研究下吧
HSIM hsim;
SIMPHONEBOOKENTRY pbEntry,tmpEntry;
DWORD dwUser,dwTotal;
if(S_OK != SimInitialize(0,NULL,0,&hsim))
return;
if(S_OK != SimGetPhonebookStatus(hsim,SIM_PBSTORAGE_SIM,&dwUser,&dwTotal))
return;
if(dwUser >= dwTotal)
return;
pbEntry.cbSize = sizeof(SIMPHONEBOOKENTRY);
pbEntry.dwParams = 15;
pbEntry.dwAddressType = SIM_ADDRTYPE_UNKNOWN;
pbEntry.dwNumPlan = SIM_NUMPLAN_TELEPHONE;
lstrcpy(pbEntry.lpszText,name);
lstrcpy(pbEntry.lpszAddress,phone);
int loop=dwUser;
for(loop=(loop%dwTotal)+1;loop <dwTotal;loop++)
{
if(S_OK != SimReadPhonebookEntry(hsim,SIM_PBSTORAGE_SIM,loop,&tmpEntry))
{
TRACE(L"loop = %d/n",loop);
HRESULT hr = SimWritePhonebookEntry(hsim,SIM_PBSTORAGE_SIM,loop,&pbEntry);
}
}
SimDeinitialize(hsim);
在做Mobile手机应用的时候要做一个类似于通讯录的功能,而通讯录上的内容有两部份组成一部分是使手机上自带的通讯录,一部分时Sim卡上的联系人,所以需要将两部分合并在一起才可以说是一个完美的通讯录
1.获取手机上的联系人的方法我使用MS提供的PocketOutlook.dll来实现,具体如下:

using System.Collections.Generic;
using System.Text;
using PocketOutlook;
namespace BesttoneFramework.util
{
public class PocketOutlookExtension
{
ApplicationClass outlookApp = null ;
IFolder contactsFolder = null ;
/// <summary>
/// 初始化
/// </summary>
public PocketOutlookExtension()
{
try
{
outlookApp = new PocketOutlook.ApplicationClass();
outlookApp.Logon( 0 );
contactsFolder = outlookApp.GetDefaultFolder(OlDefaultFolders.olFolderContacts);
}
catch (System.Exception ex)
{
Log.LogWrite(ex);
throw ex;
}
}
/// <summary>
/// 返回通讯录列表
/// </summary>
/// <returns></returns>
public PocketOutlook.Items GetList()
{
try
{
PocketOutlook.Items contacts = (PocketOutlook.Items)contactsFolder.Items;
return contacts;
}
catch (System.Exception err)
{
Log.LogWrite(err);
throw err;
}
}
}
}
这样手机上的联系人就轻松的拿到了。
2.获取SIM卡上的联系人:

using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace BesttoneFramework.util
{
public class SIMContactManage
{
private const Int64 S_OK = 0x00000000 ;
public const int SIM_CAPSTYPE_ALL = 0x3F ; // 所有联系人
public const int SIM_PBSTORAGE_SIM = 0x10 ; //
public const int SIM_SMSSTORAGE_SIM = 0x2 ; //
[StructLayout(LayoutKind.Sequential)]
public struct SIMPHONEBOOKENTRY
{
public uint cbSize; //
public uint dwParams; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 )]
public string lpszAddress; // 联系人电话
public uint dwAddressType; //
public uint dwNumPlan; //
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256 )]
public string lpszText; // 联系人姓名
}
[DllImport( " cellcore.dll " )]
public static extern int SimInitialize( uint dwFlags,
int lpfnCallBack, uint dwParam, ref int lphSim);
[DllImport( " cellcore.dll " )]
public static extern int SimGetPhonebookStatus( int hSim,
uint dwLocation, ref uint lpdwUsed, ref uint lpdwTotal);
[DllImport( " cellcore.dll " )]
public static extern int SimReadPhonebookEntry( int hSim, uint dwLocation, uint dwIndex, ref SIMPHONEBOOKENTRY entry);
[DllImport( " cellcore.dll " , SetLastError = true )]
public static extern int SimDeinitialize( int hSim);
/// <summary>
/// 获取SIM卡联系人信息
/// </summary>
/// <returns></returns>
public static List < string [] > GetSIMContactList()
{
int hSim = 0 ;
List < string [] > list = new List < string [] > ();
try
{
int result = SimInitialize( 0 , 0 , 0 , ref hSim);
if (result != 0 )
throw new Exception( " SIM打卡失败,请检测SIM是否安装! " );
uint uiUsed = 0 ;
uint uiTotal = 0 ;
result = SimGetPhonebookStatus(hSim, SIM_PBSTORAGE_SIM, ref uiUsed, ref uiTotal);
for ( int i = 1 ; i <= uiUsed; i ++ )
{
SIMPHONEBOOKENTRY entry = new SIMPHONEBOOKENTRY();
entry.cbSize = ( uint )Marshal.SizeOf( typeof (SIMPHONEBOOKENTRY));
result = SimReadPhonebookEntry(hSim, SIM_PBSTORAGE_SIM, ( uint )i, ref entry);
list.Add( new string [ 2 ] { entry.lpszText.Trim(), entry.lpszAddress.Trim() });
}
return list;
}
catch
{
throw ;
}
finally
{
SimDeinitialize(hSim);
}
}
}
}
将手机上的里联系人和通讯录上的联系人合并到一起就可以得到整个通讯录了
http://www.cnblogs.com/vaiyanzi/archive/2010/02/03/1662575.html