程序拨号及检测何时挂断的解决方案

来源:互联网 发布:mac os x ei capitan 编辑:程序博客网 时间:2024/05/16 17:54

用过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();
}