關(guān)于Symbian識(shí)別移動(dòng)、聯(lián)通和其它運(yùn)營(yíng)商網(wǎng)絡(luò)的方法
自從Symbian OS在EKA2提供了強(qiáng)大的CTelephony,這之后很多跟網(wǎng)絡(luò)相關(guān)的參數(shù)都通過這個(gè)獲取,像識(shí)別目前手機(jī)是注冊(cè)的是移動(dòng)還是聯(lián)通等信息網(wǎng)絡(luò)上傳的比較多的也是通過該方法,特別是嘯天兄在nokia論壇分享了代碼之后,網(wǎng)絡(luò)上大多采用其代碼,當(dāng)然也包括我這樣的懶人在內(nèi),而且往往很多人都沒有注意最關(guān)鍵的原理即“國(guó)際移動(dòng)用戶識(shí)別碼(IMSI:International Mobile Subscriber Identification Number)是區(qū)別移動(dòng)用戶的標(biāo)志,儲(chǔ)存在SIM卡中,可用于區(qū)別移動(dòng)用戶的有效信息。IMSI由MCC、MNC、MSIN組成,其中MCC為移動(dòng)國(guó)家號(hào)碼,由3位數(shù)字組成,唯一地識(shí)別移動(dòng)客戶所屬的國(guó)家,我國(guó)為460;MNC為網(wǎng)絡(luò)id,由2位數(shù)字組成,用于識(shí)別移動(dòng)客戶所歸屬的移動(dòng)網(wǎng)絡(luò),中國(guó)移動(dòng)為00,中國(guó)聯(lián)通為01;MSIN為移動(dòng)客戶識(shí)別碼,采用等長(zhǎng)11位數(shù)字構(gòu)成”。具體詳見http://wiki.forum.nokia.com/index.php/%E5%8C%BA%E5%88%86%E5%BD%93%E5%89%8D%E7%94%A8%E6%88%B7SIM%E5%8D%A1%E6%98%AF%E7%A7%BB%E5%8A%A8%E8%BF%98%E6%98%AF%E8%81%94%E9%80%9A
最近在使用該代碼時(shí),發(fā)現(xiàn)假如當(dāng)手機(jī)處于離線狀態(tài)下,則不論有無插SIM卡,使用嘯天兄的方法,就識(shí)別不出來了,這個(gè)應(yīng)該跟CTelephony的實(shí)現(xiàn)有關(guān),本人試著通過其源碼去了解了,但是貌似跟蹤到底層沒有完全公開,或者說個(gè)人看源碼能力還太弱了些。由于采用嘯天兄方法實(shí)現(xiàn)不了了,所以只能從上面的紅頭文件(即紅體字)尋找解決方法,雖然CTelephony::GetCurrentNetworkInfo在離線模式下失效,但是CTelephony::GetSubscriberId仍然可用,為此我們就可以通過直接分析IMSI來實(shí)現(xiàn)對(duì)運(yùn)營(yíng)商網(wǎng)絡(luò)的識(shí)別,至于MNC的信息,大家可以查詢http://en.wikipedia.org/wiki/Mobile_network_code,在國(guó)內(nèi)的情況如下截圖:
圖/MCN.JPG)
既然知道了如上信息,我們就可以簡(jiǎn)單的對(duì)IMSI號(hào)進(jìn)行分析了,小可對(duì)嘯天兄的代碼進(jìn)行簡(jiǎn)單修改,當(dāng)然該代碼也是使用CTelephony,只能使用在EKA2平臺(tái)上,EKA1可以采用RMobilePhone::GetSubscriberId的方法來獲取IMSI,在這里也就不做展開了,具體代碼如下:
頭文件
/*
* TelephonyAO.h
*
* Created on: 2010-4-22
* Author: frank
*/
#ifndef TELEPHONYAO_H_
#define TELEPHONYAO_H_
#include <e32base.h>
#include <Etel3rdParty.h>
typedef enum
{
ENetWorkUnKnow,
ENetWorkCM,
ENetWorkUN,
ENetWorkTC,
ENetWorkTT,
}TNetWorkType;
class CTelephonyAO : public CActive
{
public:
static CTelephonyAO* NewL();
TNetWorkType GetNetWorkId();
public:
~CTelephonyAO();
protected:
void DoCancel();
void RunL();
private:
CTelephonyAO();
void ConstructL();
void GetNetWorkInfo();
private:
CActiveSchedulerWait* iActiveSchedulerWait;
CTelephony* pTelephony_;
CTelephony::TSubscriberIdV1 iSubscribId;
CTelephony::TSubscriberIdV1Pckg iSubscriberIdPckg;
};
#endif /* TELEPHONYAO_H_ */
實(shí)現(xiàn)文件
/*
* TelephonyAO.cpp
*
* Created on: 2010-4-22
* Author: frank
*/
#include "TelephonyAO.h"
CTelephonyAO::CTelephonyAO() : CActive(EPriorityStandard), iSubscriberIdPckg(iSubscribId)
{
}
CTelephonyAO::~CTelephonyAO()
{
delete pTelephony_;
pTelephony_ = NULL;
delete iActiveSchedulerWait;
iActiveSchedulerWait = NULL;
}
void CTelephonyAO::ConstructL()
{
pTelephony_ = CTelephony::NewL();
iActiveSchedulerWait = new (ELeave)CActiveSchedulerWait;
CActiveScheduler::Add(this);
}
CTelephonyAO* CTelephonyAO::NewL()
{
CTelephonyAO* pSelf = new(ELeave) CTelephonyAO;
CleanupStack::PushL(pSelf);
pSelf->ConstructL();
CleanupStack::Pop();
return pSelf;
}
void CTelephonyAO::RunL()
{
if (iActiveSchedulerWait->IsStarted())
{
iActiveSchedulerWait->AsyncStop();
}
}
void CTelephonyAO::DoCancel()
{
pTelephony_->CancelAsync(CTelephony::EGetSubscriberIdCancel);
if (iActiveSchedulerWait->IsStarted())
{
iActiveSchedulerWait->AsyncStop();
}
}
void CTelephonyAO::GetNetWorkInfo()
{
Cancel();
pTelephony_->GetSubscriberId(iStatus, iSubscriberIdPckg);
SetActive();
iActiveSchedulerWait->Start();
}
TNetWorkType CTelephonyAO::GetNetWorkId()
{
GetNetWorkInfo();
TNetWorkType vNetWorkType = ENetWorkUnKnow;
if(iSubscribId.iSubscriberId.Length() < 15)
{
vNetWorkType = ENetWorkUnKnow;
}
else
{
TBuf<6> vHeader;
vHeader.Copy(iSubscribId.iSubscriberId.Left(5));
TBuf<3> vPtrTemp;
vPtrTemp.Copy(vHeader.Right(2));
TInt vNetWorkId = 0;
TLex vLex(vPtrTemp);
vLex.Val(vNetWorkId);
if((vNetWorkId == 1) ||(vNetWorkId == 6))
{
vNetWorkType = ENetWorkUN;
}
else if((vNetWorkId == 0) ||(vNetWorkId == 2))
{
vNetWorkType = ENetWorkCM;
}
else if((vNetWorkId == 3) ||(vNetWorkId == 5))
{
vNetWorkType = ENetWorkTC;
}
else if(vNetWorkId == 20)
{
vNetWorkType = ENetWorkTT;
}
else
{
vNetWorkType = ENetWorkUnKnow;
}
}
return vNetWorkType;
}
至于如何調(diào)用,就可以通過如下簡(jiǎn)單獲取了,不用再自己去比較了。
CTelephonyAO* pTelephony = CTelephonyAO::NewL();
CleanupStack::PushL(pTelephony);
TNetWorkType vNetWorkType = pTelephony->GetNetWorkId();
CleanupStack::PopAndDestroy(pTelephony);
好了,暫時(shí)小結(jié)如下吧,感謝嘯天兄前人植樹。