Due to the dangerous nature of obtaining the IMEI using a nested active scheduler, it often makes more sense to use a separate thread and get the IMEI on that.
Note that you should actually use an active object with the CAknWaitDialog to get the IMEI, but doing this is often impractical, so instead here is a solution that spawns a thread and gets the IMEI from the spawned thread.
Here is the code to get the IMEI
TBuf<32> imei;
User::LeaveIfError(GetIMEI(imei));
Here is the code for the active object
class CIMEILoader : public CActive
{
public:
CIMEILoader(TDes& aIMEI);
~CIMEILoader();
void ConstructL();
void Start();
void IMEI(TDes& aIMEI);
private:
void RunL();
void DoCancel();
private:
CTelephony* iTelephony;
TDes& iIMEI;
CTelephony::TPhoneIdV1 iId;
};
CIMEILoader::CIMEILoader(TDes& aIMEI)
: CActive(EPriorityNormal),
iIMEI(aIMEI)
{
CActiveScheduler::Add(this);
}
CIMEILoader::~CIMEILoader()
{
Cancel();
delete iTelephony;
iTelephony = NULL;
}
void CIMEILoader::ConstructL()
{
iTelephony = CTelephony::NewL();
}
void CIMEILoader::Start()
{
CTelephony::TPhoneIdV1Pckg pkg(iId);
iTelephony->GetPhoneId(iStatus, pkg);
SetActive();
}
void CIMEILoader::RunL()
{
CActiveScheduler::Stop();
iIMEI.Copy(iId.iSerialNumber);
}
void CIMEILoader::DoCancel()
{
iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel);
}
Here is the code for the thread
LOCAL_C void TelephonyHandlerL(TDes& aIMEI)
{
CActiveScheduler* sched = new (ELeave) CActiveScheduler();
CleanupStack::PushL(sched);
CActiveScheduler::Install(sched);
CIMEILoader* loader = new (ELeave) CIMEILoader(aIMEI);
CleanupStack::PushL(loader);
loader->ConstructL();
loader->Start();
CActiveScheduler::Start();
// Make sure that if we completed it was successfully
User::LeaveIfError(loader->iStatus.Int());
// When loader completes the function resumes here
CleanupStack::PopAndDestroy(2, sched);
}
LOCAL_C TInt HandlerThreadProc(TAny* aAny)
{
__UHEAP_MARK; // Heap checking
CTrapCleanup* cleanup=CTrapCleanup::New();
TInt err=KErrNoMemory;
if (cleanup)
{
TRAP(err, TelephonyHandlerL(REINTERPRET_CAST(TDes&, *aAny)));
delete cleanup;
}
__UHEAP_MARKEND;
return err;
}
Finally the helper launch the thread and get the IMEI
const TInt KTelMinHeap = 0x1000;
const TInt KTelMaxHeap = 0x4000;
_LIT(KThreadName, "TelephonyHelper");
TInt GetIMEI(TDes& aIMEI)
{
RThread theThread;
TInt err = theThread.Create(KThreadName, HandlerThreadProc, KDefaultStackSize, KTelMinHeap, KTelMaxHeap, &aIMEI);
if (err == KErrNone)
{
TRequestStatus status;
theThread.Logon(status);
theThread.Resume();
User::WaitForRequest(status);
theThread.Close();
err = status.Int();
}
return err;
}
No related wiki articles found