本文转自:http://blog.sina.com.cn/s/blog_63b4ee0d0100frq1.html
之前在项目中使用过,现将经验分享如下:
功能描述:
1.获取来电和去电的号码(此处用到S60 3rd的API);
2.对来电进行挂断(使用模拟按键和API挂断的方式);
3.修改手机的情景模式(改为静音);
4.打开/关闭音量和震动;
5.修改通话过程中听筒和话筒的音量;
6.打开/关闭免提;
7.打开/关闭手机背景光。
代码参考:(如有更好的,望指点)
#ifndef CTELDIAL_H_ #define CTELDIAL_H_ //etel core api #include <etel.h> #include <etelmm.h> #include <commdb.h> //for the vibra and ring #include <MProEngEngine.h> #include <ProEngFactory.h> #include <MProEngProfile.h> #include <MProEngToneSettings.h> #include <telephonyinternalcrkeys_partner.h> //CR Keys To Control Phone Volume #include <centralrepository.h> //CRepository //for the light #include <hwrmlight.h> //for the loud speaker #include <telephonyinternalpskeys.h> #include <e32property.h> //simulation key #include <w32std.h> class CTelDial: public CActive { public: static CTelDial* NewL(); void GetDefaultTSY(TDes& aTSYName); void StartObserve(); //the dial void GetDialNumber(); void SetDialNumber(const TDes& aSetDialNumber); bool CmpDialedNumber(); void OpenLoudSpeaker(); void SetCallVolumn(const TInt aspeakvol); //the receive void GetReceivedNumber(); void SetReceiveNumber(const TDes& aSetReceiveNumber); bool CmpReceivedNumber(); //detect void SetDetectNumber(const TDes& aSetDetectNumber); bool CmpDetectNumber(); //light and vibra void SetVibraAndRing(); void RecoverVibraAndRing(); //simulate key void SimulateRedKey(); void SimulateRightKey(); //release void ReleaseOneCall(); ~CTelDial(); protected: void RunL(); void DoCancel(); private: CTelDial(); void ConstructL(); static CTelDial* NewLC(); private: //const TUid KUidSound =0x101f8798; //Etel Api private: TBuf <20>iTSYName; RTelServer iServer; RPhone iPhone; RPhone::TLineInfo iphonelineinfo; RLine iLine; RLine::TLineInfo ilineinfo; RCall::TStatus iCallStatus; //from the etelmm RMobileCall iMCall; //the numbers private: TBuf <11> iNumberDial; TBuf <11> iNumberReceive; TBuf <11> iNumberDialSet; TBuf <11> iNumberReceiveSet; TBuf <11> iNumberDetectSet; //to change the repository private: CRepository* irepository; //for the vibra and ring private: TBool ivibratype; TProfileRingingType iRingingType; private: CHWRMLight* ilight; private: RWindowGroup iwindowgroup; //simulate key private: RWsSession ws; TRawEvent ev1; }; #endif #include <e32svr.h> #include <f32file.h> #include "CTel_3rd.h" //constructed function void CTelDial::ConstructL() { //add the cteldial to the active scheduler CActiveScheduler::Add(this); ilight = CHWRMLight::NewL(); itelephony = CTelephony::NewL(); // iwindowgroup.CaptureKey(EStdKey) } //RunL ,if the number received is equel to the setted number void CTelDial::RunL() { if (KErrNone == iStatus.Int()) { switch (iLineStatus.iStatus) { case CTelephony::EStatusDisconnecting: { ilight->LightOffL(CHWRMLight::EPrimaryDisplayAndKeyboard); RProperty::Set(KTelephonyAudioOutput,KTelephonyAudioOutputPreference,EPSPrivate); if (irepository) { delete irepository; irepository = NULL; } break; } case CTelephony::EStatusDialling: { GetDialNumber(); if (CmpDialedNumber()) { SimulateRedKey(); } break; } case CTelephony::EStatusRinging: { //turn off the vibra and ring the moment the phone is open GetReceivedNumber(); if (CmpReceivedNumber()) { SimulateRedKey(); ilight->LightOffL(CHWRMLight::EPrimaryDisplayAndKeyboard); } //compare the detect number, if it is, answer it. else if (CmpDetectNumber()) { // SetVibraAndRing(); //this is to turn off the ring SimulateRightKey(); itelephony->AnswerIncomingCall(iStatus, iCallid); //ilight->LightOffL(CHWRMLight::EPrimaryDisplayAndKeyboard); OpenLoudSpeaker(); SetCallVolumn(0); } else { //if it's the normal call, recover the vibra and ring //turn off it when the call is over RecoverVibraAndRing(); } break; } default: { ilight->LightOffL(CHWRMLight::EPrimaryDisplayAndKeyboard); break; } } } Cancel(); //if the status of line changes, it means some one is calling this phone itelephony->NotifyChange(iStatus, CTelephony::EVoiceLineStatusChange, iLineStatusPckg); } //---------------------------------------------------- //CTelDial::StartObserve() //observe the call //---------------------------------------------------- void CTelDial::StartObserve() { Cancel(); //if the status of line changes, it means some one is calling this phone itelephony->NotifyChange(iStatus, CTelephony::EVoiceLineStatusChange, iLineStatusPckg); SetActive();//invoke the asynchronous function } //---------------------------------------------------- //CTelDial::SetVibraAndRing() //turn off the vibra and ring //---------------------------------------------------- void CTelDial::SetVibraAndRing() { MProEngEngine* iEngine = ProEngFactory::NewEngineL(); MProEngProfile* iProfile = iEngine->ActiveProfileLC(); MProEngToneSettings& iToneSetting = iProfile->ToneSettings(); //if vibra is on, turn off it ivibratype = iToneSetting.VibratingAlert(); if (ivibratype) { iToneSetting.SetVibratingAlert(EFalse); } //turn off the ring iRingingType = iToneSetting.RingingType(); if (EProfileRingingTypeSilent != iRingingType) { iToneSetting.SetRingingType(EProfileRingingTypeSilent); } iProfile->CommitChangeL(); iProfile->Release(); iEngine->Release(); } //---------------------------------------------------- //CTelDial::RecoverVibraAndRing() //recover the vibra and ring //---------------------------------------------------- void CTelDial::RecoverVibraAndRing() { MProEngEngine* iEngine = ProEngFactory::NewEngineL(); MProEngProfile* iProfile = iEngine->ActiveProfileLC(); MProEngToneSettings& iToneSetting = iProfile->ToneSettings(); //recover iToneSetting.SetVibratingAlert(ivibratype); iToneSetting.SetRingingType(iRingingType); iProfile->CommitChangeL(); iProfile->Release(); iEngine->Release(); } //---------------------------------------------------- //CTelDial::GetReceivedNumber() //get the incoming call number //---------------------------------------------------- void CTelDial::GetReceivedNumber() { //in the 3rd CTelephony::TCallInfoV1 iPhonyCallInfoV1; CTelephony::TCallInfoV1Pckg iPhonyCallInfoV1Pckg(iPhonyCallInfoV1); CTelephony::TCallSelectionV1 iPhonyCallSelectionV1; CTelephony::TCallSelectionV1Pckg iPhonyCallSelectionV1Pckg(iPhonyCallSelectionV1); CTelephony::TRemotePartyInfoV1 iPhonyRemotePartyInfoV1; CTelephony::TRemotePartyInfoV1Pckg iPhonyRemotePartyInfoV1Pckg( iPhonyRemotePartyInfoV1 ); CTelephony::TCallStatusV1 iPhonyCallStatusV1; CTelephony::TCallStatusV1Pckg iPhonyCallStatusV1Pckg(iPhonyCallStatusV1); iPhonyCallSelectionV1.iLine = CTelephony::EVoiceLine; iPhonyCallSelectionV1.iSelect = CTelephony::EInProgressCall; itelephony->GetLineStatus(CTelephony::EVoiceLine, iPhonyCallStatusV1Pckg); itelephony->GetCallInfo(iPhonyCallSelectionV1Pckg, iPhonyCallInfoV1Pckg, iPhonyRemotePartyInfoV1Pckg); if (CTelephony::ERemoteIdentityAvailable == iPhonyRemotePartyInfoV1.iRemoteIdStatus) { if (iPhonyRemotePartyInfoV1.iRemoteNumber.iTelNumber.Length() > 0) { //Incoming call number iNumberReceive = iPhonyRemotePartyInfoV1.iRemoteNumber.iTelNumber; } } } //---------------------------------------------------- //CTelDial::GetDialNumber() //get the outgoing call number //---------------------------------------------------- void CTelDial::GetDialNumber() { CTelephony::TCallInfoV1 iPhonyCallInfoV1; CTelephony::TCallInfoV1Pckg iPhonyCallInfoV1Pckg(iPhonyCallInfoV1); CTelephony::TCallSelectionV1 iPhonyCallSelectionV1; CTelephony::TCallSelectionV1Pckg iPhonyCallSelectionV1Pckg(iPhonyCallSelectionV1); CTelephony::TRemotePartyInfoV1 iPhonyRemotePartyInfoV1; CTelephony::TRemotePartyInfoV1Pckg iPhonyRemotePartyInfoV1Pckg( iPhonyRemotePartyInfoV1 ); iPhonyCallSelectionV1.iLine = CTelephony::EVoiceLine; iPhonyCallSelectionV1.iSelect = CTelephony::EInProgressCall; itelephony->GetCallInfo(iPhonyCallSelectionV1Pckg, iPhonyCallInfoV1Pckg, iPhonyRemotePartyInfoV1Pckg); if (iPhonyCallInfoV1.iDialledParty.iTelNumber.Length() > 0) { //Outgoing call number iNumberDial = iPhonyCallInfoV1.iDialledParty.iTelNumber; } } bool CTelDial::CmpDialedNumber() { if (iNumberDialSet == iNumberDial) { return true; } else { return false; } } bool CTelDial::CmpReceivedNumber() { if (iNumberReceiveSet == iNumberReceive) { return true; } else { return false; } } bool CTelDial::CmpDetectNumber() { if (iNumberDetectSet == iNumberReceive) { return true; } else { return false; } } void CTelDial::SetDialNumber(const TDes& aSetDialNumber) { iNumberDialSet.Copy(aSetDialNumber); } void CTelDial::SetReceiveNumber(const TDes& aSetReceiveNumber) { iNumberReceiveSet.Copy(aSetReceiveNumber); } void CTelDial::SetDetectNumber(const TDes& aSetDetectNumber) { iNumberDetectSet.Copy(aSetDetectNumber); } //---------------------------------------------------- //CTelDial::OpenLoudSpeaker() //open the loudspeaker //---------------------------------------------------- void CTelDial::OpenLoudSpeaker() { TInt value; TInt theerr = RProperty::Get(KTelephonyAudioOutput, KTelephonyAudioOutputPreference, value); switch(value) { case EPSPrivate: { theerr = RProperty::Set(KTelephonyAudioOutput,KTelephonyAudioOutputPreference,EPSPublic); break; } default: break; }; } void CTelDial::SetCallVolumn(const TInt aspeakvol) { //To create a CRepository object for accessing Phone Volume repository: //and it must be created while the phone is processing irepository = CRepository::NewL(KCRUidCallHandling); //turn the speaker's volumn to max TBuf<10> lBufErr; TInt lErr = irepository->Set(KTelephonyIncallLoudspeakerVolume, aspeakvol); lBufErr.AppendNum(lErr); if (KErrNone != lErr) { return; } } void CTelDial::SimulateRedKey() { ws.Connect(); ev1.Set(TRawEvent::EKeyDown, EStdKeyNo); ws.SimulateRawEvent(ev1); User::After(100000); ev1.Set(TRawEvent::EKeyUp, EStdKeyNo); ws.SimulateRawEvent(ev1); ws.Flush(); } void CTelDial::SimulateRightKey() { ws.Connect(); ev2.Set(TRawEvent::EKeyDown, EKeyDevice1); ws.SimulateRawEvent(ev2); User::After(100000); ev2.Set(TRawEvent::EKeyUp, EKeyDevice1); ws.SimulateRawEvent(ev2); ws.Flush(); } CTelDial::CTelDial() : CActive(CActive::EPriorityStandard),iLineStatusPckg(iLineStatus) { iLineStatus.iStatus = CTelephony::EStatusUnknown; } void CTelDial::DoCancel() { itelephony->CancelAsync(CTelephony::EVoiceLineStatusChangeCancel); } CTelDial::~CTelDial() { delete ilight; } //the three new functions CTelDial* CTelDial::NewLC() { CTelDial* self = new (ELeave) CTelDial; CleanupStack::PushL(self); self->ConstructL(); return self; } CTelDial* CTelDial::NewL() { CTelDial* self = CTelDial::NewLC(); CleanupStack::Pop(self); return self; }