跟一声响骚扰说“拜拜”

模仿功能:模拟来电

模仿对象:来电通

模仿进度:第二期

开发平台:Windows Mobile平台

手机铃声响起,一两声过后就挂了,被“一声响”电话骚扰很烦吧。如果开发一个手机铃声延迟的工具,会非常受用户的欢迎。

响铃延迟设计思路

Windows Mobile 智能手机提供了常见的来电铃声配置功能,来电响铃一般有6种常见模式供用户选择。但是很多时候,我们往往需要其他一些特殊的响铃模式来过滤一声响的骚扰电话(工具下载地址:http://www.shudoo.com/bzsoft)。

例如,手机来电时,先震动n秒,然后才正常响铃;手机来电时,LED灯闪烁n秒后,才正常响铃;手机来电时,手机无任何反应,n秒后铃声才正常响起。用户可以根据自己的喜好设置不同的模式。

要避免不受“一声响”电话的骚扰,我们需要为手机设定特殊的响铃方式。来电之后,前3秒并不响铃(时间可以修改),根据用户选择的模式(用系统的响铃设计脚本),进行震动或者LED灯闪烁或者静音。3秒之后,才播放来电铃声(图1)。

clip_image002

响铃脚本的妙用

Windows Mobile系统的响铃模式,是由其响铃脚本控制的。该脚本是一串特定指令组成的字符串,保存在注册表项HKEY_CURRENT_USER\Controlpanel\Sounds\RingTone0\Script之中。要修改响铃模式,我们只需对该注册表值进行设定便可。脚本的指令集由a、p、v、f、w、c、r几个字母组成,这几个指令分别表示的意思是:

a:active device,激活设备,指令r循环的起点。

p:play ringtone,播放铃声(在执行下一个代码之前将一直播放铃声)。

v:vibrate,振动几秒,v0表示一直震动。

f:flash,闪烁 LED几秒,如“f5”表示闪烁5秒。

w:wait,等待(暂停),如“w0”表示取消铃声间的间隔时间。

c: change volume,改变音量到最大音量的百分比,可以超过100,如“c50”表示改变音量为50%。

r:repeat script,重复执行脚本,一般放在整个脚本的最末,表示重复执行整段脚本。

光看这几条指令不够直观,下面我们举例解释一下。

l “渐强铃声”的脚本为:“c50apw3c150r”,这段脚本的意思是:c50:调整为50%的音量;p:响铃;w3:等3秒;c150r:设音量为150%,再重复执行。

l “振动并响铃”的脚本为:“av0pw3r”,这段脚本的意思是:一直振动(v0)响铃,歌曲播完后停3秒(w3),再重复(r)播放。

l 之前提到的,我们需要先震动一段时间,再响铃的情况,可以在“振动并响铃”的脚本加上v10(先震动10秒),像这样设置:“v10av0pw3r”。

响铃延迟开发步骤

第一步:创建项目

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

第二步:设计界面

右击“解决方案资源管理器”中的“Form1.cs”,重命名为“FormCfg.cs”,Visual Studio 2008的重构功能会自动将该窗体的类名修改为“FormCfg”。在“窗体设计器”选中该窗体,在“属性”浮动窗口中修改该窗体的“Text”属性为“RingToneScript”。从“工具箱”浮动窗口中拖放控件到“FormCfg”窗体上完成界面设计(图2)。

clip_image004

第三步:读写响铃脚本

前面提到过,响铃脚本保存在注册表项HKEY_CURRENT_USER\Controlpanel\Sounds\RingTone0\Script之中。这里我们需要读取该注册表项并进行更新,.NET CF中提供了操作注册表的函数Microsoft.Win32.Registry。关键码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

        /// <summary>
        /// 读取当前振铃脚本
        /// </summary>
        /// <returns>当前振铃脚本</returns>
        private string ReadScript()
        {
            string script = string.Empty;
            using (RegistryKey registryKey =
                Registry.CurrentUser.OpenSubKey(@"\ControlPanel\Sounds\RingTone0"))//以只读方式检索
            {
                 script = registryKey.GetValue("Script").ToString();//读取键值
            }
            return script;
        }

        /// <summary>
        /// 改写振铃脚本
        /// </summary>
        /// <param name="script">振铃脚本</param>
        private void WriteScript(string script)
        {
            using (RegistryKey registryKey =
                Registry.CurrentUser.OpenSubKey(@"\ControlPanel\Sounds\RingTone0",true))//以可写方式打开
            {
                registryKey.SetValue("Script",script, RegistryValueKind.String);//设置键值
            }

        }

需要注意的是,某些机器安全配置很高,写注册表项需要程序具有相应的权限。所以我们还要对程序的特权证书进行签名,具体方法就这里不再赘述了。

第四步:设置模式

在这里,就要设置用户选择免骚扰的模式了。依次双击“窗体设计器”中“FormCfg”的几个按钮,分别为其添加对应的响应代码。关键码如下所示(完整代码下载地址:http://www.shudoo.com/bzsoft):

        /// <summary>
        /// 先震动
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonV_Click(object sender, EventArgs e)
        {
            WriteScript("v" + numericUpDownV.Value.ToString() + strScript);//在原始振铃脚本前添加震动指令
            MessageBox.Show("OK");
        }
…… ……
        /// <summary>
        /// 还原
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonReSet_Click(object sender, EventArgs e)
        {
            WriteScript(strScript);
            MessageBox.Show("OK");
        }

第五步:运行程序

在Visual Studio 2008中点击菜单“调试→启动调试”(或者直接按F5),在弹出的部署对话框中选择“Windows Mobile 6 Professional Device”(如果不是真机与电脑连接,那么选择“Windows Mobile 6 Professional Emulator”,则会启动模拟器),点击“部署”,部署完成之后便会在终端上自动启动程序,选择一种模式再拨一下你的电话,看看,来电响铃的模式是不是改变了?

读者反馈

开发QQ群:看了上期的文章,感觉来电界面还不是很逼真,请问怎么能进一步提高仿真度?

小编:第一,窗体顶部可以绘制成圆角。.NET CF 未提供绘制圆角矩形的函数,我们可以通过XrossOne来实现此功能。XrossOne Mobile GDI+ 是一种开放源代码的二维图形引擎,它是用 C# 代码编写的。

它可以帮助 .NET Compact Framework 开发人员创建高质量的矢量图形输出。具体使用方法请到:http://www.microsoft.com/china/msdn/library/NetFramework/netcompactframework/dnnetcompXrossOne.mspx?mfr=true查看。

第二,使用Notification控件,通过这个控件,可以让来电界面更加逼真。Notification控件的使用方法请到http://msdn.microsoft.com/zh-cn/library/microsoft.windowsce.forms.notification.aspx查看。

开发QQ群:上期的模拟来电,我觉得非常好,我有一个设想,可以不按键(那样太明显了),晃动一下手机来电就响起。这个功能可以实现吗?

小编:目前有部分手机内置了重力感应装置,该装置能够感应到手机的水平倾斜、上下左右晃动等动作,通过调用重力感应对应的API,即可实现该功能。iPhone、HTC G1、M8、Nokia5800等机型都内置了该装置。

开发QQ群:我在窗体上绘制图片的时候,常常会有闪烁的问题,请问应该怎么解决?

小编:闪烁的问题是由于绘制与重绘的速度过慢,完成绘制的时长过长而产生的。提高.NET CF下的绘图效率,即可解决这个问题。不使用OnPaint事件,而是直接重写窗体的OnPaint方法;不使用e.Graphics,直接通过this.CreateGraphics()创建Graphics ;采用双缓冲技术开辟一个内存缓冲区,将图片先在内存里面准备好,再将内存内的图片完整的绘制到窗体上。

读者问题:在发送手机短信时,如何获知短信是否发送成功?

高手 amysmsMessage.RequestDeliveryReport属性,表示是否要求送达通知。我们在调用smsAccount.Send发送短信之前,将该属性设置为true。那么,在短信发出之后,运营商网关便会回复一条短信回执。通过该回执我们可以得知短信是否成功送达目的手机。

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

 

(载《电脑报》2009年22期)

原文地址:https://www.cnblogs.com/tanjian/p/1634206.html