转自这里

一、双卡双待背景分析

用户为了兼顾运营商优势,使用双卡双待手机:

双卡双待这项技术在发展中国家使用很普遍,因为在发展中国家电信运营商发展不够成熟,相关管理制度不完善。从用户的角度出发,主要考虑资费问题,比如:移动通话信号好,联通3G上网流畅、流量费相对便宜,为了兼顾运营商的优势,用户选择双卡双待手机。

运营商为了争夺原有2G用户,推出双卡双待手机:

原有国内六大运营商中国移动,中国联通,中国电信,中国网通,中国铁通和中国卫通,经过了整合与拆分,用户在使用制式上各有不同包括GSM、TD-SCDMA、WCDMA、CDMA2000;其中GSM占有量非常大,各运营商在推广新业务时,不得不兼顾原有GSM用户。例如电信如果手机只能使用电信卡,市场上推广会有很多障碍,运营商通过推出双卡双待来解决这个问题。

双卡双待相关技术发展:

  • 两套芯片,缺点是耗电量大、硬件成本高。这个相当于是两个手机“粘”在一起。

  • 双卡单待,需要手动切换,不是真正的双卡双待,用户只能使用一张卡。相当于加了一个“开关”。

  • 双卡双待,使用芯片控制手机在两个网络之间切换,因为切换速度很快用户感觉是两张卡在同时待机。是目前采用的技术手段。

二、双卡双待碎片化现状

双卡方案不统一:

Android本身碎片化问题严重,Google标准API中没有双卡双待的支持,对于双卡双待实现方式业界也没有标准,于是双卡解决方案有了现在百花齐放、百家争鸣的局势。

涉及模块众多:

作为一个智能手机平台,电话部分是Android系统的重点功能。电话部分主要功能包括:呼叫(Call)、短信(Sms)、数据连接(Data Connection)、Sim卡相关、电话本等。尽管Android整个框架已经使用AIDL机制来解耦,使得各个模块之间尽可能的独立,但对于开发者和产品人员来说,所有涉及到这些模块的功能点都会受到双卡双待的困扰。

已成事实标准的双卡双待逼迫主流厂家开始支持:

在过去双卡双待是山寨手机的一个代名词,山寨机是最早发现这块需求并快速响应;后面随着用户的普及,很多大手机厂商纷纷推出双卡双待手机,包括一些在国外市场只支持单卡的机型,也会在国内做好了双卡双待,才推向市场。

最新的HTC One在国内没有单卡机器售卖,原本一体的机身设计,后经改装加入双卡双待功能。三星S系列也逐渐铺开双卡机型,双卡双待已经不是小众用户,也不是低端用户,这个现状对于开发者是个绕不过的坎儿。如果要开发电话模块相关的功能,开发团队必须要解决双卡双待的问题。

三、解决策略

双卡双待实现和真机ROM的Framework层实现密切相关,不同的手机实现方式不一样,同一系列的手机实现的策略类似,但是可能有差别。下面介绍分析解决的过程:

1、【准备工作】

工具准备:smali 和 dex2jar

详细操作流程请参见工具网站说明

https://code.google.com/p/dex2jar/

https://code.google.com/p/smali/downloads/list

材料准备:需要将适配的双卡手机 system目录下的framework 和 app目录文件提取出来备做反编译用。

2、【分析过程】

通过查看Android源代码和分析真机反编译代码可以看出Android电话模块架构主要核心机制是:一个服务(比如本文提到的电话服务)对应一个Manager管理类,一个Manager管理类对应一个AIDL接口(Android进程通信接口),每个AIDL接口会对应一个具体服务功能的实现。

电话服务 —> TelephonyManager —>PhoneInterfaceManager(ITelephony)—>底层具体服务

TelephonyManager(电话服务管理类)

Android框架中有上下文(context)的概念,很多资源和系统服务可以直接从上下文中获得,比如要获得电话管理类(TelephonyManager)可以通过下面方式获得:

context.getSystemService("phone");

我们通过context 的实现类ContextImpl可以获取对电话管理类的访问

@Override

public Object getSystemService(String name) {

ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);

return fetcher == null ? null : fetcher.getService(this);

}

所有的系统服务管理类,都注册在SYSTEM_SERVICE_MAP中。

从上图源代码中可以看到,getSystemService方法最终是靠传入对应服务的key从SYSTEM_SERVICE_MAP中获得对应的管理类,这里第一个坑爹点会出现,因为key对应的值,厂商会修改成各种值,比如有些手机是”phone2”,有些比如HTC手机是”htctelephony”,所以需要反编译厂商源码去查找这些key值,下边会详细讲到。

ITelephony(电话相关的AIDL接口)

TelephonyManager中的具体操作大部分是通过ITelephony接口访问的,比如获得电话状态的操作:

public class TelephonyManager {

...

public int getCallState() {

try {

return getITelephony().getCallState();

} catch (RemoteException ex) {

return CALL_STATE_IDLE;

} catch (NullPointerException ex) {

return CALL_STATE_IDLE;

}

}

...

}

ITelephony接口位于com.android.internal.telephony.*包中,这个包是支撑android.telephony.*对外接口的具体实现。

PhoneInterfaceManager (ITelephony的具体实现类,提供具体服务功能)

TelephonyManager大部分操作是通过ITelephony接口访问的,也就是通过其实现类PhoneInterfaceManager 来实际获得具体相关操作

public class PhoneInterfaceManager extends ITelephony.Stub {

...

public int getCallState() {

return DefaultPhoneNotifier.convertCallState(mCM.getState());

}

...

}

PhoneInterfaceManager 封装了电话相关的具体服务操作,这些操作最终将消息发送到RIL.java中转。

RIL.java和底层通信

RIL.java是电话相关服务在Java层的信息收发中心。

RIL.java使用socket和rild进程通信,RILRequest是一个请求的封装,通过RILSender将请求命令发送出去,通过RILReceiver接收命令的响应和主动消息。

经过上述的分析,可以总结出电话相关服务的架构。

3、【架构分析】

Android电话系统分为四个层次(见上图)。

Phone应用程序层:主要包括电话服务和Phone应用程序。

Java Framework层:主要包括两个程序包,其中:android.telephony.* 是framework对外沟通的接口,com.android.internal.telephony* 是和底层沟通的桥梁(socket )。

Native Framework层: Rild守护进程。

驱动层:与网络进行沟通传输。

为了支持双卡双待功能,厂商实现的Java Framework层在TelephonyManager的节点向下开始自定义API实现对第二张卡的支持,通过反编译并分析真机的framework.jar可以得到自TelephonyManager以下厂商自定义的操作。然后,在App层通过反射调用对应的功能点就可以实现对两张卡的操作。

4、【解决方案举例】

通过对市面上大部分双卡机型的反编译分析看,双卡双待的解决方案可以总结为3类:

TelephonyManager异化:三星、Moto系列

这类真机中提供了两个电话服务管理类,通过context.getSystemService("phone2")可以得到电话服务类中的第二张卡的电话服务管理类。这个方案属于最有节操的,开发成本是最低的。

在android.app.ContextImpl中注册上下文的各种管理类,以下为Google官方代码中的实现:

以下是反编译三星 Node2 framework.jar得到的相关代码块

registerService("phone", new ServiceFetcher()

{

public Object createService(ContextImpl paramContextImpl)

{

return new TelephonyManager(paramContextImpl.getOuterContext(), 0);

}

});

registerService("phone2", new ServiceFetcher()

{

public Object createService(ContextImpl paramContextImpl)

{

return new TelephonyManager(paramContextImpl.getOuterContext(), 1);

}

});

可以看出通过context.getSystemService("phone2"),就可以从上文中提到的SYSTEM_SERVICE_MAP拿到第二张卡的管理类,因为只是管理类实例不一样,只需要拿到第二张卡的TelephonyManager实例,所有的方法都可以按照标准API正常使用。

方法异化:MTK芯片系列

MTK解决方案广泛用于联想以及中兴厂商中,这类手机没有新建Manager管理类,而是在管理类中新加入xxxGemini(int para)的方法,其中int参数代表卡槽,0为一卡槽,1为二卡槽。开发者需要通过反射来调用和标准API对应的Gemini方法来实现对应的操作。以下为反编译 联想A750 对应的获得Sim卡状态的方法具体实现。

public int getSimState()

{

return getSimStateGemini(getDefaultSim());

}

public int getSimStateGemini(int paramInt)

{......}

调用对应的Gemini方法可以实现对两张卡的操作,比如:通过反射调用getSimStateGemini分别传入0和1作为参数,就可以获得两张卡的SIM卡状态。

新建Manager类:华为系列

这种方案比较隐蔽的,通过修改增加自己实现类完成对双卡的支持,以下为华为C8825D的处理方案:

首先,得到对应的管理类

c = Class.forName("android.telephony.MSimTelephonyManager");

//其中MSimTelephonyManager类为厂商自定义的电话服务管理类

然后,通过反射调用对应的方法,可以成功的返回操作结果

method = c.getDeclaredMethod("getSimState", int.class);

四、总结

双卡双待手机的适配过程主要是分析“异化”点,找到在Framework层中是如何区分卡槽的,不同的手机实现不同,对于TelephonyManager相关的解决方案总结有以上三种。对于短信相关的操作位于SmsManager中,解决策略和TelephonyManager类似,不再详细分析。

经过上面的分析过程可以知道,一个模块的功能点,适配开发过程中都需要进行下面三个步骤:

(1)反编译系统framework.jar、phone.apk等找到对应功能不同卡槽的操作方式。

(2)在本地代码中通过反射调用该方法。

(3)验证操作是否成功。

过程相对比较复杂,需要反复的试验和验证,而且每款手机都要这样调查和解决一遍,因此开发成本是相当高的。

Android 双卡双待相关推荐

  1. Android 双卡双待支持检验SIM信息获取

    Android 双卡双待支持检验及SIM信息获取 本文将从应用开发者的角度分析手机是否支持双卡双待,获取如果说希望自己做出支持双卡双待的系统,本文估计就不适合你了,能力不足,还望见谅啊 好了,为了迎合 ...

  2. Android 双卡双待识别

    简介 Android双卡双待已经越来越普及了,解决双卡双待管理是广大手机开发人员必须得面对的问题,为实现Android平台的双卡双待操作,笔者研究了Android 应用层操作双卡双待的机制. 机制 获 ...

  3. android 双卡识别,Android 双卡双待识别

    简介 Android双卡双待已经越来越普及了,解决双卡双待管理是广大手机开发人员必须得面对的问题,为实现Android平台的双卡双待操作,笔者研究了Android 应用层操作双卡双待的机制. 机制 获 ...

  4. 解决 Android 双卡双待识别

    Android开发的问题 其实很好狠.今天看到一篇解决android 机型 双卡 管理的问题.看到一篇比较好的文章就转载过来了 = = 转载:http://blog.csdn.net/banketre ...

  5. Android 双卡双待手机解析短信异常分析及解决

    如有转载,请声明出处: 时之沙:http://blog.csdn.net/t12x3456 开发中,难免会遇到各种各样的适配问题,尤其是经过深度修改定制过的系统,有的无论是软硬件上都有很大的区别,这里 ...

  6. Android双卡双待编程识别

     如今,尤其是在中国,双卡双待如此普及和如此广泛,双卡双待已经成为智能手机的事实上的标准.大势所趋,为此,Android从Android 5.1开始,从Android SDK API层面开始支持双 ...

  7. Android 双卡双待 资料

    From 这里 摘要:为实现Android 平台上的双网双待功能,研究Android 平台的系统架构以及Android framework 层上已经实现的双卡处理机制.提出一种在无线接口层( RIL) ...

  8. android 双卡双待 发送短信

    最近公司拿了一批手机是FRG83G的双卡机子,在程序中按照普通的发短信调用方法,短信发不出去,经过研究,目前android的双卡手机有两个插槽,一个是GSM,另外一个是CDMA,对应的卡也必须插正确, ...

  9. 双卡双待智能android,双卡双待智能Android 酷派D539正式开售

    (中关村在线手机频道行情报道)2011年4月24日,酷派D539(行货)在"酷派官方网上商城"处的最新报价为2080元.这款手机的配件为:电池.充电器.耳机.数据线.酷派D539是 ...

  10. 双卡手机发送短信 - 坑爹的双卡双待

    最近要写一个Android app,其中一个功能要发短信,直接照抄Android API Demos的例子OS\SMS Messaging,在自己的手机上测试,发现总是报错SmsManager.RES ...

最新文章

  1. Linux下开发优秀链接
  2. 一次单核CPU占用过高问题的处理
  3. GRE OVER IPSEC
  4. 4到20ma模拟量转换公式_西门子 S7-1200 模拟量转换
  5. dotnet core 数据库
  6. 无线打印服务器 惠普打印机,连接您的HP无线打印机 | 无线打印中心 | 惠普中国...
  7. 从官网下载jdk1.6 1.7
  8. android:windowSoftInputMode属性使用
  9. dz php表单发送邮件,php 发送邮件
  10. C#.NET快速开发框架-企业版V4.0截图打包下载
  11. Mac如何设置允许和iCloud之间使用接力功能?
  12. VS2010 在Win 7 附加w3wp.exe进程进行调试
  13. js call与apply函数
  14. 【软件分析/静态程序分析学习笔记】3.数据流分析(Data Flow Analysis) (上):可达性分析(Reaching Definitions)
  15. 四火的唠叨51CTO访谈--有关面试
  16. conda冗余package的清理(.conda/pkgs)
  17. Android博通BCM libbt-vendor.so 分析蓝牙初始化流程
  18. 用java写出杨辉三角。
  19. 聚丙烯酸(PAA)修饰纳米Fe3O4四氧化三铁粒子|CNTs/Fe3O4/TiO2纳米复合材料(齐岳)
  20. 用C#简单实现迷你理财工具

热门文章

  1. (转)罗振宇跨年演讲:哪来直接登顶的人生,只有不断迭代的历程
  2. query相关搜索词推荐
  3. 计算机专业的优秀学长寄语大一新生,学长学姐对大一新生的寄语 大学学长学姐寄语励志...
  4. 联想服务器怎么装系统和配置,联想服务器的配置及操作系统的安装.pdf
  5. Js Switch语句
  6. 恒指交易如何先小亏,后而才是大赚!
  7. SpringCloud Sleuth入门介绍
  8. swoole安装教程人人商城互动直播通信服务启用教程
  9. 深度理解感受野(一)什么是感受野?
  10. python彩色螺旋线_python绘制彩色螺旋线