Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9417887
  • 博文数量: 1748
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20070
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1748)

文章存档

2024年(24)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: LINUX

2009-06-10 09:35:16

当我们开始编写Android的电话应用程序的时候,如果需要进行电话拨号,可以进行如下调用:
ITelephony tpCallModule = (ITelephony)ITelephony.Stub.asInterface(ServiceManager.getService("phon"));
tpCallModule.dial("13800138000");

而对于短信的应用,我们需要调用的则是SmsManager:
SmsManager SMS = SmsManager.getDefault();
SMS.sendTextMessage("13420926323",null,"this is a test sms",null,null);

到底Android是如何跟底层GSM模块通讯的呢?我一开始就猜测是不是跟WM那样采用RIL的架构来实现,查看了google的官方文档,证实 了我的猜测是正确的,Android里面的确采用了RIL架构跟底层GSM模块通讯,先看看RIL在Android里的位置吧。

Android的RIL在这里被做成一个叫做rild的库,通过一个系统环境变量ro.radio.noril是否为空来决定要不要把RIL的代码 编译进内核,这点跟CE的编译方式是一样的,如果设置了该变量,将会有个"SimulateCommand"的玩意编译进内核,它可以在没有实际GSM硬 件的情况下模拟部分实际硬件的指令,然后让RIL驱动提供给上层应用,如果没有设置该系统环境变量就会采用RIL。

通过研究RIL的代码可以看到,Android的rild库是介于HAL接口与baseband modem之间,它同样提供了语音、数据、短信、SIM卡管理以及STK应用的功能,实现思路跟微软的RIL有异曲同工之妙,也是把标准的 GSM27.007中常用的如dial这些做主动请求的操作称之为request,一共75个;另外一类GSM模块主动上报的例如信号强度、基站信息等, 称之为unsolicited response,一共17个;开发模式也是跟微软RIL开发差不多,需要针对不同的GSM模块进行不同的GSM驱动开发,公用的部分google给你做 好了,特定的部分需要你自己去定制,这样做可以大大地提高开发效率。
RIL跟上层通讯主要采用两种方式,一种是通过Socket发送与接收消息的方式来实现,这个Socket在ril.cpp里面可以找到它的创建代码:
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
还有另外一种方式就是直接通过TCP/IP直接访问内核中的shared memory,进行RPC调用,这种方式主要应用在数据模式上,一来由于Android的每个Activity随时都会有可能需要网络连接接收发送数据, 因此必须提供一种实时性较高访问的方式,二来可以提高通讯效率。

其实最上层的ITelephony和SmsManager有点像WM里面的Connection Manager,呵呵,有意思,这是不是其实印证了一句话“万变不离其宗”呢?

如何构建Android电话应用
2009-03-23 15:47

本文为御风独舞原创,转载请注明出处:hi.baidu.com/roooy,谢谢:)

上次介绍了一下Android的RIL架构,我们可以把它理解为是GSM模块的驱动,这次要介绍的是Telephony这个组件,我们把它和 WinCE做对比,发现它其实就是做了CellCore做的工作,只是CellCore依然很面向过程地单纯导出SDK,然后让上层驱动调用。 Telephony由于是运行在我们的Dalvik虚拟机上面的,所以它的实现也就更面向对象化了。接下来让我们看看怎么使用这个Telephony库开 发我们的电话应用。

Telephony库主要负责Android的拨打与接听电话功能,其中有两个重要的类分别是IPhone和PhoneNumberUtils是我 们实现电话功能必不可少的。当我们的应用需要拨打一个号码的时候,Android默认是没有授予我们这个应用的这个权限的,因此我们必须在 AndroidManifest.xml中去打开这个权限。AndroidManifest.xml是每一个应用都需要的文件,它位于应用的根目录下,文 件里描述了程序包的全局变量,包括暴露的应用组件(activities, services等等)和为每个组件的实现类,以及什么样的数据可以操作和它在什么地方运行。现在我们在里面添加一行:

从此我们的应用就拥有了拨打电话的权限了,接下来就是建立一个IPhone类的对象,上次我已经介绍了必须要通过ServiceManager来获得,以下代码演示了如何建立一个IPhone类对象:
private static IPhone getPhoneInterface() throws DeadObjectException
{
IServiceManager sm = ServiceManagerNative.getDefault();
IPhone phoneService = IPhone.Stub.asInterface(sm.getService("phone"));
return phoneService;
}
一旦建立完了IPhone对象,即可使用call或者dail方法来拨电话了:
void call(String number)
void dial(String number)
它们之间的差别就是call是在后台进行的,一般用于数据传输(gprs,edge)的应用,而dial是会显示一个简单的拨号界面,上面预设了你的参数作为拨号的号码,如果给dial的参数传入NULL,则会调用拨号的界面显示出来。

还有一种简单的拨号方法,有仔细看Intent文档的人就会发现,对一个电话格式的网址(如href="tel: (+86)1234567890")发送出CALL_ACTION,就可以调用拨号程序对其进行拨号。这种方便的方法可以在开发我们的浏览器应用的时候, 直接在浏览网页的时候正则匹配到电话号码,然后直接调用拨号程序对其拨号,很方便吧。

获取电话的属性可以通过TelephonyProperties来实现,比如SIM卡,IMEI等信息,我们可以通过调用 os.SystemProperties.put()方法传入TelephonyProperties的字段来设置对应的参数,也可以通过 os.SystemProperties.get()方法获取这些参数,以下是一些实际引用的例子:
获取本机号码,调用android.os.SystemProperties.get(PROPERTY_LINE1_NUMBER);
获取IMEI,调用android.os.SystemProperties.get(PROPERTY_IMEI);
获取运营商名字,调用android.os.SystemProperties.get(PROPERTY_SIM_OPERATOR_ALPHA);
获取国家代码,调用android.os.SystemProperties.get(PROPERTY_SIM_OPERATOR_ISO_COUNTRY);
获取语音信箱号码,调用哪个android.os.SystemProperties.get(PROPERTY_LINE1_VOICE_MAIL_NUMBER);



阅读(2816) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~