您的位置:首页 > 其它

来电过滤 全靠防火墙

2009-12-28 16:09 141 查看
模仿功能:来电防火墙

模仿对象:来电通

模仿进度:第三期

开发平台:Windows Mobile平台

有些电话不愿接,有些电话不必接,有些电话不能接……你需要一个“来电防火墙”。

来电防火墙设计思路

提起防火墙,大家可能很快就会想到电脑上常用的“××个人防火墙”。在手机平台,有一种特殊的防火墙,它能将部分来电进行屏蔽。经常收到骚乱电话的用户、经常需要拒听来电的朋友,就需要来电防火墙。

设计一个“来电防火墙”软件,基本的思路是这样的(图1):

设置过滤(拦截)规则:一般可以考虑电话号码的黑、白名单,全部/部分拦截,分时段拦截等等。

截获来电:即截获到手机有电话拨入的消息。

获取来电号码:如果基于电话号码的黑白名单,或者要记录拦截日志,则需要在截获到来电之后,解析出来电的号码。

拒接/转接来电:程序控制拒接来电,如果需要对方听到“电话已关机”、“此号码已停机”、“号码不存在”等系统提示音,则可以使用AT指令,将来电转接到特定的电话号码上。





如何监视并截获来电

监视并截获来电,通常有RIL、TAPI、托管的SystemState等3种方式。

方式1:RIL

RIL(Radio Interface Layer)是应用处理器与基带处理器之间交互的一组接口。工作在PPP、TCP/IP协议之下,负责数据的可靠传输、AT命令的发送以及response的解析。通过RIL,我们可以实现与GSM/GPRS或者CDMA2000 1X Modem通信,从而能够监视并截获基带处理器中的来电信息。

方式2TAPI

所谓TAPI,即电话应用程序接口(Telephony Application Program Interface),是一套用来编写与电信业务相关的程序的函数。TAPI提供了通用的方法来对付各种各样的种类繁多的硬件,可以监视和截获来电信息。

方式3:SystemState

.NET CF提供了一系列系统状态的notification,包括:SystemProperty.PhoneCallCalling, SystemProperty.PhoneIncomingCall,SystemProperty.PhoneIncomingCallerNumber, SystemProperty.PhoneCallTalking等。通过这几个函数的取值组合,能得到目前电话状态,是正在拨出?还是有来电?还是电话已接通?还是电话已挂断?

上述三种方式,由于RIL最接近系统底层,所以性能最好响应速度最快,TAPI次之,SystemState方式响应最慢。但是同时RIL开发难度最大,而且由于各厂商的RIL具体实现有所差异,所以开发的程序可能存在兼容性问题。而.NET CF提供的SystemState方式,兼容性好,容易理解,开发难度小,我们在这里就选用这种方式进行开发。

来电防火墙开发步骤

第一步:创建项目

启动Visual Studio 2008,选择“文件→新建项目”。在弹出的“新建项目”的“项目类型”中选择“Visual C#→智能设备”,“模板”选“智能设备项目”,“名称”设为“CallFirewall”。在弹出的“添加新智能设备项目”对话框中,“目标平台”选择“Windows Mobile 6 Professional SDK”,“.Net Compact Framework 版本”选择“.Net Compact Framework Version 3.5”,“模板”选“设备应用程序”完成项目创建。

第二步:添加程序集引用

在新创建的项目中,程序集“Microsoft.WindowsMobile.Status”并未默认引用,在这里我们需要手动添加引用。在“解决方案资源管理器”内,右击“引用”,点击菜单项“添加引用”,在弹出的“添加引用”对话框中,选择“.NET”标签,在组件列表中,选中“Microsoft.WindowsMobile.Status”,点击“确定”。重复上述步骤,添加程序集“Microsoft.WindowsMobile”的引用。

第三步:添加来电监视

在“窗体设计器”里面,双击主窗体,添加窗体的Load事件响应。FormMain_Load方法体内,添加的关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

//窗体载入
private void FormMain_Load(object sender, EventArgs e)
{
SystemState phoneIncomingCall = new SystemState(SystemProperty.PhoneIncomingCall);//呼入状态监视
SystemState phoneIncomingCallerNumber = new SystemState(SystemState.PhoneIncomingCallerNumber);//来电号码状态监视
phoneIncomingCall.Changed += new ChangeEventHandler(phoneIncomingCall_Changed);//事件处理
phoneIncomingCallerNumber.Changed += new ChangeEventHandler(phoneIncomingCallerNumber_Changed);//事件处理
}

//来电号码事件处理
void phoneIncomingCallerNumber_Changed(object sender, ChangeEventArgs args)
{
throw new NotImplementedException();
}
//呼入状态事件处理
void phoneIncomingCall_Changed(object sender, ChangeEventArgs args)
{
throw new NotImplementedException();

第四步:添加拒接代码

前面提及的RIL与TAPI方式都可以实现来电的拒接,也可以实现来电转接,感兴趣的可以自行实验,这里不做赘述。在这里,我们采用的是模拟手机“挂机”键按下的方式,来拒接电话。添加的关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

//模拟一次挂机按键操作
public static void Drop()
{
keybd_event(VK_F4, 0, 0, 0);
keybd_event(VK_F4, 0, KEYEVENTF_KEYUP, 0);
}
//End键的VK键值 F4
private const int VK_F4 = 0x73;
private const int KEYEVENTF_KEYUP = 0x0002;
//keybd_event API用于想系统发送按键消息
[DllImport("coredll.dll")]
static extern void keybd_event(

第五步:处理来电

将来电的号码跟列表中的号码进行比对,如何是需要拒接的电话,则进行挂断操作。添加的关键代码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

string incomingNumber = string.Empty;//记录来电号码
List<string> BannedList = new List<String>();//拒接电话列表

//呼入状态事件处理
void phoneIncomingCall_Changed(object sender, ChangeEventArgs args)
{
try
{
if (BannedList.Exists((s) => // 判断是否为要过滤的电话
{
s = incomingNumber;
return (from t in BannedList
where t.Equals(s)
select t).Count() == 0 ? false : true;
}))
Drop();// 挂断

第六步运行程序

在Visual Studio 2008中点击菜单“调试→启动调试”(或者直接按F5),在弹出的部署对话框中选择“Windows Mobile 6 Professional Device”(如果不是真机与电脑连接,那么选择“Windows Mobile 6 Professional Emulator”,则会启动模拟器),点击“部署”,部署完成之后便会在终端上自动启动程序。如果使用模拟器的话,我们可以使用SDK中提供的“蜂窝模拟器”来模拟电话呼叫(图2)。





读者反馈

开发QQ群:看了第21期关于开发“模拟来电”的文章,我试了一下,碰到一个问题,特来请教。文章说,在“目标平台”中选择“Windows Mobile 6 Professional SDK”,为什么我的Visual Studio 2008中没有这个选项?只有 PPC SDK?我安装的可是完整版的Visual Studio 2008。

小编:要在VS2008中进行WM6的开发,需要先安装Windows Mobile 6 Professional SDK Refresh.msi、Windows Mobile 6 Professional Images (CHS).msi两个包。前者为SDK包,后者为模拟器映像包。这两个安装包,都可以到MSDN里面下载。

开发QQ群:上期文章介绍的拒绝“一声响”的3种模式,我一个都不满意。我觉得最好的方式是来电铃声逐渐增大,这个这个怎么实现?

小编:可以将注册表项HKEY_CURRENT_USER\Controlpanel\Sounds\RingTone0\Script修改为“c50apw3c150r”,这段脚本的意思是:c50:调整为50%的音量;p:响铃;w3:等3秒;c150r:设音量为150%,再重复执行。还可以参照上期文章中“响铃脚本的妙用”一节里面的脚本指令介绍,自己定义更多精彩的响铃方式。

开发QQ群:我有一个疑问,设计手机铃声相关的程序,必须要涉及系统函数吗?用Java可以开发不?

小编:由于跨平台的需要,Java ME并未提供直接操作注册表的方法。不建议使用Java开发此类程序。

开发QQ群:我在群里面看到有人说蜂窝模拟器,我没有接触过这个东东,它是什么?怎么使用?

小编:在许多情况下,应用程序要跟系统的通信功能进行交互,为了解决测试这种应用程序的困难,Windows Mobile 6 SDK 提供了 Cellular Emulator(蜂窝仿真器)。Cellular Emulator能够测试应用程序在各种蜂窝通信的情况下的状况。

用 Cellular Emulator 可以执行一些简单的测试,例如在仿真器中拨打电话,接听来电和挂断电话,发送和接收 SMS 信息等。为了让开发人员可以测试更复杂的功能,Cellular Emulator 还支持对 SIM 配置信息的修改,还有选择2G网络还是3G网络。所有这些测试工作都不需要用到一台物理设备。点击“开始菜单→Windows Mobile 6 SDK→Tools→Cellular Emulator”,便可运行蜂窝模拟器。

读者问题:在指定的时间启动模拟来电,可以使用定时器Timer组件实现。但是如果手机休眠了?或者手机重启了?如何让程序在指定的时间启动?

高手 阿木:可以使用函数BOOL CeRunAppAtTime(TCHAR* pwszAppName, SYSTEMTIME* lpTime)设定指定的程序在指定的时间运行。需要特别指出的是,第二个参数是SystemTime的结构,这在.NET Compact Framwork中需要进行特殊的转换。函数具体描述可参考MSDN,http://msdn.microsoft.com/en-us/library/ms913957.aspx 。另外,OpneNETCF中提供的LargeIntervalTimer也可以实现该功能。

读者问题:在某些特殊情况下,需要自动拒接所有的来电,但同时自动回复给对方一条短信以示礼貌,比如“现在正在开会,稍后回复您”等等,我想问问这个功能应该怎么设计?

(载《电脑报》2009年25期)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: