[Windows Mobile] RIL来电监听简单使用

 

  自己负责一个类似来电显示的小软件,来电监听模块使用TAPI实现,之前一直不忙,日常工作只是版本维护。这次公司提出新需求,就想借这次机会,把来电监听模块重写。

  总结了一些Windows Mobile平台电话监听的几种实现方式:

  1.TAPI :此方法较为简单,脱离了底层硬件,协议统一,所以使用TAPI实现电话监听不会有特例性,各家手机均支持。但是TAPI所在层比较高,得到电话信息也就较慢一些。

  2.RIL: 硬件之上就是它了,最先得到电话信息,但是有OEM特性,各家实现方式不统一,所以不好匹配所有机型。不过使用它灵活性最大。所以如果使用RIL做电话监听,最大的问题就是如何去异求同。

  3.监控注册表: 所有电话信息都会写注册表,所以监控注册表也就成了电话监听的一种“歪门邪道”。这种方式肯定不能第一时间得到电话事件,并且需要不停的监控注册表,实在是下策。故不采用。

  4.AT指令:通过AT指令也可以实现(2010.9.26 更新)

 

  RIL的简单使用

sdk里是没有带ril库的,自己下载ril.lib。

把.h .lib添进工程

 

  1.实现这两个函数

void CALLBACK RilNotifyProc(DWORD dwNotifyCode, const void* pData, DWORD dwDataSize, DWORD dwParam);

void CALLBACK RilResultProc(DWORD dwResultCode, HRESULT hrCommandID, const void* pData, DWORD dwDataSize, DWORD dwParam);

  2.初始化RIL

HRIL       g_hRil;

HRESULT hr = RIL_Initialize(1, RilResultProc, RilNotifyProc, RIL_NCLASS_CALLCTRL, NULL, &g_hRil);

  3.卸载RIL

RIL_Deinitialize(g_hRil);

 

  测试RIL寻求共性

 

  测试发现Windows Mobile的一款手机(WM5.0),它只响应 RIL_NOTIFY_RING;RIL_NOTIFY_CONNECT;RIL_NOTIFY_DISCONNECT这3个事件,并且来电时,如果不接听则会连续产生RIL_NOTIFY_RING事件。当本机接听来电,则会产生RIL_NOTIFY_CONNECT事件。 不管哪方挂断电话产生RIL_NOTIFY_DISCONNECT事件。
经过模拟器,Windows Mobile5/6其它实机的测试,总结做来去电监听的思路如下:
对每个事件(RIL_NOTIFY_RING;RIL_NOTIFY_CONNECT;RIL_NOTIFY_DISCONNECT)只响应一次,假定A、B两方。

A给B打电话:A响应一次RIL_NOTIFY_CONNECT表示去电(除RIL_NOTIFY_DISCONNECT再不响应其它事件);B响应一次RIL_NOTIFY_RING表示来电(除RIL_NOTIFY_DISCONNECT再不响应其它事件)。

 

  贴出部分代码(不要觉得奇怪,没办法不同手机响应不同,所以写的比较奇怪。不能直接使用,只是让大家看一下逻辑,怎么实现共性的可以通用在不同手机上)

 

/*******************************************************

Copyright (C), 2010, tamer

FileName: CRilMonitor.cpp

Author: tamer Version : 1.0.0   Date: 2010/08/28

Description:   

Version: 1.0.0

Function List:



History: 

<author>    <time>   <version >   <desc>

 tamer 2010/08/28   1.0.0    build this moudle  

********************************************************/

#include <windows.h>

#include "CRilMonitor.h"





#pragma comment(lib, "ril/ril.lib")



#define RIL_CALLDIR_NONE (0x00000000)



CRilMonitor* CRilMonitor::s_pThis = NULL;



void CALLBACK CRilMonitor::RilResultProc(DWORD dwResultCode, HRESULT hrCommandID, const void* pData, DWORD dwDataSize, DWORD dwParam)

{  

	switch ( dwResultCode )   

	{   

	case RIL_RESULT_OK:   

		{  

			RILCALLINFO *pCallInfo = ((RILCALLINFO *)pData); // must call RIL_GetCallList



			if ( pCallInfo != NULL)  

			{

				if (RIL_CALLDIR_INCOMING == pCallInfo->dwDirection)

				{

					//DEBUGMSG(TRUE, (TEXT("Result status:%d\n"), pCallInfo->dwStatus));

					DEBUGMSG( TRUE, ( TEXT("来电号码:%s\n"), pCallInfo->raAddress.wszAddress) ); 

					_tcscpy(s_pThis->m_szPhoneNum, pCallInfo->raAddress.wszAddress);

					if (s_pThis->m_lpfnIncomingCall != NULL)

					{

						s_pThis->m_lpfnIncomingCall(s_pThis->m_szPhoneNum);

					}

				}

				if (RIL_CALLDIR_OUTGOING == pCallInfo->dwDirection)

				{

					DEBUGMSG( TRUE, ( TEXT("去电号码:%s\n"), pCallInfo->raAddress.wszAddress) );

					_tcscpy(s_pThis->m_szPhoneNum, pCallInfo->raAddress.wszAddress);

					if (s_pThis->m_lpfnDialingCall != NULL)

					{

						s_pThis->m_lpfnDialingCall(s_pThis->m_szPhoneNum);

					}

				}				  

			}  

			break;   

		}

	}  

}



void CALLBACK CRilMonitor::RilNotifyProc(DWORD dwNotifyCode, const void* pData, DWORD dwDataSize, DWORD dwParam)

{

	//DEBUGMSG(TRUE, (TEXT("RilNotifyCode:%d\n"), dwNotifyCode^RIL_NCLASS_CALLCTRL));

	switch(dwNotifyCode)

	{

	case RIL_NOTIFY_RING:

		if (!s_pThis->m_bFlag)

		{

			s_pThis->m_bFlag = TRUE;

			RIL_GetCallList( s_pThis->m_hRil );

		}

		break;

	case RIL_NOTIFY_CONNECT:

		if (!s_pThis->m_bFlag)

		{

			s_pThis->m_bFlag = TRUE;

			RIL_GetCallList( s_pThis->m_hRil );

		}

		break;

	case RIL_NOTIFY_DISCONNECT:

		if (s_pThis->m_bFlag)

		{

			s_pThis->m_bFlag = FALSE;

			DEBUGMSG(TRUE, (TEXT("挂断电话!\n")));

			if (s_pThis->m_lpfnDisconnectedCall != NULL)

			{

				s_pThis->m_lpfnDisconnectedCall(s_pThis->m_szPhoneNum);

			}

		}

		break;

	case RIL_NOTIFY_CALLSTATECHANGED:

		if (s_pThis->m_bFlag)

		{

			s_pThis->m_bFlag = FALSE;

			DEBUGMSG(TRUE, (TEXT("挂断电话!\n")));

			if (s_pThis->m_lpfnDisconnectedCall != NULL)

			{

				s_pThis->m_lpfnDisconnectedCall(s_pThis->m_szPhoneNum);

			}

		}

		break;

	case RIL_NOTIFY_CALLPROGRESSINFO:

		{		

			//DEBUGMSG(TRUE, (TEXT("Notify Direction:%d, status:%d\n"),prci->dwDirection, prci->dwStatus));

			if (s_pThis->m_bFlag)

			{

				RILCALLINFO* prci = (RILCALLINFO*)pData;

				if (RIL_CALLDIR_NONE == prci->dwDirection &&

					RIL_CALLSTAT_ALERTING == prci->dwStatus)

				{

					s_pThis->m_bFlag = FALSE;

					DEBUGMSG(TRUE, (TEXT("挂断电话!\n")));

					if (s_pThis->m_lpfnDisconnectedCall != NULL)

					{

						s_pThis->m_lpfnDisconnectedCall(s_pThis->m_szPhoneNum);

					}

				}

			}

		}

		break;

	}

}   







int CRilMonitor::InitMonitor(LPVOID lpParamer)

{

	HRESULT hr = RIL_Initialize(1, RilResultProc, RilNotifyProc, RIL_NCLASS_CALLCTRL/*RIL_NCLASS_ALL*/, NULL, &m_hRil);

	

	if (FAILED(hr))

	{

		DEBUGMSG(TRUE, (TEXT("RIL_Initialize err:%d\n"), GetLastError())); 

		return -1;

	}



	return 0;

}



void CRilMonitor::UninitMonitor(LPVOID lpParamer)

{

	RIL_Deinitialize(m_hRil);

	m_hRil = NULL;

}

 

 

只是简单的实现,其它功能还有待挖掘。

 

 

  几个重要的参数

/////////////////////////////Call status values//////////////////////////////////////
RIL_CALLSTAT_ACTIVE               Active call.
RIL_CALLSTAT_ONHOLD             Call on hold.
RIL_CALLSTAT_DIALING            In the process of dialing.
RIL_CALLSTAT_ALERTING            In the process of ringing.
RIL_CALLSTAT_INCOMING          Incoming (unanswered) call.
RIL_CALLSTAT_WAITING           Incoming call waiting call.

 

////////////////////////////////Call direction/////////////////////////////
RIL_CALLDIR_INCOMING             Incoming call.
RIL_CALLDIR_OUTGOING             Outgoing call.

 

下载:

RIL库文件

RIL相关资料

你可能感兴趣的:(Windows Mobile)