S60获取SIM电话本

S60获取电话本信息,如果获取手机中的电话本并不难,网上有很多资料。但在获取SIM联系人的时候遇到困难,甚至网上有人说Nokia不支持。

还好,没有被这些吓到,继续在网上搜索资料。在网上逛了N久,终于找到了相关办法。Nokia并不是禁止获取SIM联系人,而是S60的SDK中并没有提供这方面的公开API。

感谢“冰岛”大虾提供方法。


以下代码在5230上测试通过,注意,需要加入capabilities : ReadUserData 

还需要一些头文件和lib,可在http://www.cnblogs.com/yaoliang11/archive/2011/04/19/2020740.html下载


struct AspContactList
{
    TBuf<30> iName;
    TBuf<30> iTel;
};

void CSimContast::GetSimCardContactListL(RArray<AspContactList>& aRecords)
{
	RTelServer telServer;
	User::LeaveIfError(telServer.Connect());
	CleanupClosePushL(telServer);
	
	TRequestStatus status;
	RTelServer::TPhoneInfo info;
	telServer.GetPhoneInfo(0, info);

	RMobilePhone phone;
	User::LeaveIfError(phone.Open(telServer, info.iName));
	CleanupClosePushL(phone);
	
	RMobilePhoneBookStore bookStore;


	//ETel的 sub-session 的名字从 "S1" 到 "S29"
	//sim卡上的通信录格式是 "ADN", 下面3个名字包含 ADN
	//_LIT(KETelMeAdnPhoneBook,"S1");
	//_LIT(KETelTaAdnPhoneBook,"S6");
	//_LIT(KETelIccAdnPhoneBook,"S7");

	const TInt storenum[] = { 1, 6, 7, };
	TUint j = 0;
	for ( ; j < sizeof(storenum) / sizeof(storenum[0]); j++ )
	{
		
		TBuf<10> storename;
		storename.Copy(_L("S"));
		storename.AppendNum(storenum[j]);
	
		TInt err = bookStore.Open(phone, storename);
		
		if ( err != KErrNone )
		{ //open failed, try next
			
			continue;
		}
		CleanupClosePushL(bookStore);
	
		RMobilePhoneBookStore::TMobilePhoneBookInfoV1 storeInfo;
		RMobilePhoneBookStore::TMobilePhoneBookInfoV1Pckg storeInfoPckg(storeInfo);
		bookStore.GetInfo(status, storeInfoPckg);
		User::WaitForRequest(status);
		
		
		if ( status.Int() != KErrNone ) 
		{
			
			CleanupStack::PopAndDestroy();
			continue;
		}
	
		if ( storeInfo.iUsedEntries < 1 )
		{ //not record
			
			CleanupStack::PopAndDestroy();
			continue;
		}
	
		HBufC8* hbuf = HBufC8::NewLC(storeInfo.iTotalEntries * 100);
		TPtr8 recordbuf = hbuf->Des();
		// Read the own number entry
		status = KRequestPending;
		bookStore.Read(status, 1, storeInfo.iTotalEntries, recordbuf);
		User::WaitForRequest(status);
		if ( status.Int() != KErrNone )
		{
			
			CleanupStack::PopAndDestroy(hbuf);
			continue;
		}
	
		//下面解析 ADN 的数据, 没有现成代码, 网上找不到ADN格式, 只是根据数据逆向解析, 可能有bug
		AspContactList record;
		TInt pos = 0; //pos
		TInt len = recordbuf.Length();
		while ( pos < len )
		{
			if ( recordbuf[pos] == RMobilePhoneBookStore::ETagPBNewEntry && pos != 0 )
			{ //new record and not is first ETagPBNewEntry
				if ( record.iName.Length() != 0 || record.iTel.Length() != 0 )
				{
					aRecords.AppendL(record);
				}
			record.iName.Zero();
			record.iTel.Zero();
			}
	
			//新的栏位前面应该有个0x00
			if ( recordbuf[pos++] != 0x00 )
			{
				continue;
			}
			if ( pos >= len - 3 )
			{ // not have a full tlv
				break;
			}
	
			if ( recordbuf[pos] == RMobilePhoneBookStore::ETagPBText )
			{ //name
				pos++;
				TInt namelen = recordbuf[pos] + recordbuf[pos+1] * 256;
				pos += 2; //length has 2 bytes
				if ( (pos + namelen) > len )
				{ //data error
					break;
				}
				namelen = Min(namelen, record.iName.MaxLength() * 2);
				record.iName.Copy((const TUint16*)(recordbuf.Ptr() + pos), namelen / 2);
				pos += namelen;
			} 
			else if ( recordbuf[pos] == RMobilePhoneBookStore::ETagPBNumber )
			{ //tel number
				pos++;
				TInt tellen = recordbuf[pos] + recordbuf[pos+1] * 256;
				pos += 2;
				if ( (pos + tellen) > len )
				{ //data error
					break;
				}
				tellen = Min(tellen, record.iTel.MaxLength() * 2);
				record.iTel.Copy((const TUint16*)(recordbuf.Ptr() + pos), tellen / 2);
				pos += tellen;
			}
		}
		
		if ( record.iName.Length() != 0 || record.iTel.Length() != 0 )
		{ //last record
			aRecords.AppendL(record);
		}
		CleanupStack::PopAndDestroy(2);
	}

	CleanupStack::PopAndDestroy(2);
}

问题解决了,心情舒畅一下。 微笑
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值