摘要:移动开发者社区开发杂志《Windows Phone应用开发专题 第一季》中我参与编写的部分,《Windows Mobile设备常见任务开发》。主要介绍了Windows Mobile中最常见的几个开发任务,如拨打电话、发送短信、联系人管理等等,点此转到索引页。本节主要介绍如何在Windows Mobile应用程序中打电话和发短信。
语音呼叫与短消息,是所有手机最基本、最常用的功能。本节中,我们一起来了解一下在Windows Mobile 6中这两个功能的托管代码(C#)实现。
根据经验,我们一般会认为语音呼叫与短消息属于同类操作,因为他们都属于基本通信功能。而事实上,在Windows Phone中,语音呼叫与短消息功能相关的类分别位于不同的命名空间中,相反的,短消息与电子邮件这两个似乎无关的功能,却是用的同一个命名空间。
具体各个功能主要涉及的命名空间详情如下:
Microsoft.WindowsMobile.Telephony命名空间很简单,只包含一个表示语音呼叫的Phone类。而Phone类也很简单,除构造方法外,可用方法基本上只有一个用于发起呼叫Talk方法。也就是说,在托管代码中,对语音呼叫能进行的操作基本上只有一个发起呼叫。要对语音通话进行其他更多的控制,可能给需要用TAPI(Telephony Application Program Interface)或者借助第三方封装类库来实现,这些已经超出了本文的讨论范围。
下面我们一起看一下如何调用Talk方法以发起语音呼叫。Talk方法有两种形式的重载,其中第一种只接收一个要呼叫的电话号码,然后发起呼叫;第二种允许同时传入一个布尔值来决定是否在发起呼叫前提醒用户,请求确认。如下面右图所示,如果用户选择否,呼叫将会取消。
下面的代码片段示范了根据复选框ckDisplayPromt是否勾选来确定发起呼叫时是否提醒用户,其中txbPhoneNumber.Text既是呼叫的电话号码。运行效果即上面的截图。
private void btnDial_Click(object sender, EventArgs e) { Phone thePhone = new Phone(); if (ckDisplayPromt.Checked) { thePhone.Talk(txbPhoneNumber.Text,true); } else { thePhone.Talk(txbPhoneNumber.Text); } }
Microsoft.WindowsMobile.PocketOutlook命名空间中主要封装了两个本地API,一个是前一节了解过的POOM,另一个就是这里要用到的Windows CE Mail 。Windows CE Mail用于处理设备上的电子邮件和短消息。发送短消息要用的就是这个命名空间下的SmsMessage类。
我们只需了解一下SmsMessage类的公开属性就可以用这个类来发送SMS短消息了:
下面的代码片段示范了向四个指定的接收者发送一条短消息。
private void miSend_Click(object sender, EventArgs e) { SmsMessage message = new SmsMessage(); message.Body = txbBody.Text; message.RequestDeliveryReport = ckbRequstReport.Checked; message.To.Add(new Recipient("14250010001")); if (receiver1 != null) message.To.Add(receiver1); if (receiver1 != null) message.To.Add(receiver2); if (receiver1 != null) message.To.Add(receiver3); message.Send(); }
运行界面截图如下。
关于SMS短消息相关开发,需要补充说明的几点:
用于截获短消息的托管类MessageInterception位于Microsoft.WindowsMobile.PocketOutlook.MessageInterception命名空间中,是从Windows Mobile 5.0开始引入的。通过该该功能,应用程序可以侦听设备收到的短消息,当截获到符合指定规则的消息时,可以触发相应的事件。
截获规则由MessageCondition类定义。一条截获规则可以描述为“消息的**属性”“包含/开始于/结束于/等于”“**字符串”。具体可参考MessageCondition类的最常用的构造方法重载。
在MessageInterception类中,截获规则表现为属性MessageCondition,而截获成功时触发的事件处理程序则通过MessageReceived事件来指定。
下面的代码片段定义了一个消息截获器,当截获到Body属性中包含“MagicBoy”字符串的消息时,会触发相应的MessageReceived事件,调用interceptor_MessageReceived事件处理程序。
private void Form_InterceptSms_Load(object sender, EventArgs e) { MessageInterceptor interceptor = new MessageInterceptor(); interceptor.MessageCondition = new MessageCondition (MessageProperty.Body,MessagePropertyComparisonType.Contains,"MagicBoy"); interceptor.MessageReceived += new MessageInterceptorEventHandler(interceptor_MessageReceived); } void interceptor_MessageReceived(object sender, MessageInterceptorEventArgs e) { MessageBox.Show("收到一条包含‘MagicBoy’的短消息!"); }
下图的截屏中我们可以看到,左图发送的测试消息中包含了"MagicBoy"关键字,因而出发了处理程序;而右图消息未包含关键字,没有触发。
通过截获短消息然后解析消息内容的方法,我们可能实现一些很有趣、或有用的功能,譬如用短信远程控制设备、对等网络传输等。但是在使用短消息来实现这些功能时,必须考虑其成本,因为运营商对短消息一般都是按条收费的,另外也要考虑到短消息本身的字数限制。
电子邮件与SMS短消息位于同一个命名空间。事实上更密切的,电子邮件消息类EmailMessage与SMS短消息类SmsMessage派生自同一个基类Message。这也就意味着电子邮件的操作和短消息是类同的。
所不同的是,SmsMessage的Send方法会将消息立即发送出去,而EmailMessage的Send方法只是将消息放到发件箱中,等待用户自行建立网络连接进行数据交换,当然,我们可以通过MessagingApplication.Synchronize ()方法强制执行发送和接收。
如下的代码演示了这一过程。
private void miSend_Click(object sender, EventArgs e) { EmailMessage email = new EmailMessage(); email.To.Add(new Recipient("MagicBoy","[email protected]")); email.Subject = txbSubject.Text; email.BodyText = txbBody.Text; email.Send(new OutlookSession().EmailAccounts[0]); MessagingApplication.Synchronize(); }
另外需要补充的是,无论是电子邮件消息还是SMS消息,我们除了通过Send方法发送以外,还可以通过MessagingApplication.DisplayComposeForm方法打开一个预置了一些选项(如接收者、消息内容等)的标准系统新消息窗口,等待用户编辑完善消息后再自行发送。
如下面一行代码打开了一个预置收件人和邮件主题的标准新建电子邮件窗口,运行效果如上面右图。
private void micompose_Click(object sender, EventArgs e) { EmailMessage email = new EmailMessage(); email.To.Add(new Recipient("MagicBoy","[email protected]")); email.Subject = txbSubject.Text; MessagingApplication.DisplayComposeForm(email); }
示例代码下载:TelephoneAndSms.zip
小结:通过本节的学习,我们了解了在托管代码中进行语音呼叫、SMS发送、SMS截获及电子邮件发送的基本方法。结合上一节中了解过的POOM,我们已经可以编写一些常用的语音、短信类应用。实践是最好的老师,试着设计一个使用语音、短信的小软件,马上打开VS动手做一下吧!祝学习愉快!