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

问题解决了,心情舒畅一下。微笑
阅读更多
个人分类: Symbian
想对作者说点什么? 我来说一句

S60 3rd Edition SDK

2008年12月23日 125KB 下载

Android 获取手机SIM资料

2011年09月08日 6KB 下载

S60V2FC模拟器.sis

2008年12月31日 106KB 下载

Gameloft S60机型经典全集

2007年04月13日 15.68MB 下载

诺基亚S60通用模拟器

2010年02月07日 292KB 下载

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭