用过Nokia智能手机的人都知道,当电话拨通以后,原来的程序就被切换到后台运行去了,但是当电话挂断以后,Nokia并没有把原来的程序给切换到前台,不知道Nokia为什么要这样做.本篇给出一份代码,内容包括拨号,CallBack电话挂断事件,把原来的程序切换到前台.
/*
* ============================================================================
* Name : CDailEngine from CDailEngine.h
* Part of : None
* Created : 08.08.2006 by Zhaojiangwei
* Last Modifed: 22.08.2006
* Implementation notes:
*
* Version : 1.0
* Copyright: All rights reserved
* ============================================================================
*/
#ifndef __DAILENGINE_H__
#define __DAILENGINE_H__
#include <etel.h>
class MPhoneCallClientObserver
{
public:
virtual void HandleCallHungUpL() = 0;
};
class CDailEngine:public CActive
{
public:
static CDailEngine* NewL(MPhoneCallClientObserver& aObserver);
~CDailEngine();
public:
// CActive
virtual void RunL();
virtual void DoCancel();
public:
void MakeCallL(const TDesC& aNumber);
private:
// the state of this object governs what happens when the
// StartL() / Stop() / RunL() / DoCancel() functions are called.
enum TState
{
ENoState,
EDialling,
EWatching
};
private:
CDailEngine(MPhoneCallClientObserver& aObserver);
void ConstructL();
private:
void StartL();
void Stop();
void InitCallServerL();
void TelephonyCleanup();
private:
MPhoneCallClientObserver& iObserver;
RCall iCall;
RTelServer iServer;
RPhone iPhone;
RLine iLine;
RCall::TStatus iCallStatus;
TState iState;
TPtrC iNumber;
};
#endif
/*
* ============================================================================
* Name : CDailEngine from CDailEngine.cpp
* Part of : None
* Created : 08.08.2006 by Zhaojiangwei
* Last Modifed: 22.08.2006
* Implementation notes:
*
* Version : 1.0
* Copyright: All rights reserved
* ============================================================================
*/
#include "DailEngine.h"
_LIT (KTsyName,"phonetsy.tsy");
CDailEngine::CDailEngine(MPhoneCallClientObserver& aObserver)
:CActive(EPriorityNormal),
iObserver(aObserver), iState(ENoState)
{
}
CDailEngine::~CDailEngine()
{
Cancel();
TelephonyCleanup();
}
CDailEngine* CDailEngine::NewL(MPhoneCallClientObserver& aObserver)
{
CDailEngine* self = new (ELeave) CDailEngine(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CDailEngine::ConstructL()
{
CActiveScheduler::Add(this);
}
void CDailEngine::MakeCallL(const TDesC& aNumber)
{
iState = EDialling;
InitCallServerL();
iNumber.Set(aNumber);
StartL();
}
void CDailEngine::InitCallServerL()
{
iServer.Connect();
iServer.LoadPhoneModule(KTsyName);
//Find the number of phones available from the tel server
TInt numberPhones;
User::LeaveIfError(iServer.EnumeratePhones(numberPhones));
//Check there are available phones
if (numberPhones < 1)
{
User::Leave(KErrNotFound);
}
//Get info about the first available phone
RTelServer::TPhoneInfo info;
User::LeaveIfError(iServer.GetPhoneInfo(0, info));
//Use this info to open a connection to the phone, the phone is identified by its name
User::LeaveIfError(iPhone.Open(iServer, info.iName));
//Get info about the first line from the phone
RPhone::TLineInfo lineInfo;
User::LeaveIfError(iPhone.GetLineInfo(0, lineInfo));
//Use this to open a line
User::LeaveIfError(iLine.Open(iPhone, lineInfo.iName));
}
void CDailEngine::StartL()
{
switch(iState)
{
case ENoState:
return;
case EDialling:
{
User::LeaveIfError(iCall.OpenNewCall(iLine));
iCall.Dial(iStatus, iNumber);
break;
}
case EWatching:
iCall.NotifyStatusChange(iStatus, iCallStatus);
break;
}
SetActive();
}
void CDailEngine::RunL()
{
// if the caller hangs up, then we will get KErrGeneral error here
if(iState == EDialling && iStatus.Int() == KErrGeneral)
{
Stop();
iObserver.HandleCallHungUpL();
return;
}
if(iStatus.Int() != KErrNone)
return;
switch(iState)
{
case EDialling:
iState = EWatching;
StartL();
break;
case EWatching:
User::LeaveIfError(iCall.GetStatus(iCallStatus));
if(iCallStatus == RCall::EStatusHangingUp || iCallStatus == RCall::EStatusIdle)
{
Stop();
iObserver.HandleCallHungUpL();
}
else
{
StartL();
}
break;
default:
break;
}
}
void CDailEngine::DoCancel()
{
Stop();
}
void CDailEngine::Stop()
{
switch(iState)
{
case ENoState:
break;
case EDialling:
iCall.HangUp();
iCall.Close();
break;
case EWatching:
iCall.NotifyStatusChangeCancel();
iCall.Close();
break;
}
iState = ENoState;
}
void CDailEngine::TelephonyCleanup()
{
//free up the resource
iPhone.Close();
iLine.Close();
iServer.Close();
}