Android 双卡双待识别

简介

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

 

机制

获取基于ITelephony接口实现phone应用中的“phone服务”,通过TelephonyManager接口获取不同的卡(GSMPhone /CDMAPhone)进行不同的操作(拨号、接通、挂断、保持通话等)。

Android平台是一个多样型的平台,不同的手机获取ITelephony接口不同,用一种方法实现双卡双待管理是不可取的。那怎么办呢?只有针对不同的手机分析出一套管理的方案,该方案实现难度大,因为需要各个厂家的SDK的资料。为了实现该功能,笔者做了大量工作,整合各个厂家的SDK的资料。

 

实现

为了更好的管理双卡双待的问题,新建一个双卡双待模块静态库,其它项目引用便是,项目如图:

 

效果如图:

小米手机 测试效果

 

华为手机测试效果

 

 

 

AbsSim是抽象类,负责实现手机操作的类。不同的厂家继承该类实现各自的接口。AbsSim信息如下:

 

[cpp] view plaincopy
 
  1. public abstract class AbsSim implements IDualDetector { //抽象基类  
  2.     protected final String TAG = getClass().getSimpleName();  
  3.     protected ArrayList<SimSlot> mSimSlots = new ArrayList<SimSlot>();  
  4.     protected boolean mIsDualSimPhone = false;  
  5.     protected String mCallLogExtraField = "";  
  6.   
  7.     public abstract String getSimPhoneNumber(int paramInt); // 返回手机号码  
  8.   
  9.     public abstract int getDataState(int paramInt);// 返回数据状态  
  10.   
  11.     public abstract String getIMSI(int paramInt);// 返回手机标识  
  12.   
  13.     public abstract String getIMSI(int paramInt, Context paramContext);// 返回手机标识  
  14.   
  15.     public abstract int getPhoneState(int paramInt);// 返回手机状态  
  16.   
  17.     public abstract boolean isServiceAvaliable(int paramInt);// 服务是否可用  
  18.   
  19.     public abstract boolean isSimStateIsReady(int paramInt);// 卡是否在使用  
  20.   
  21.     public abstract int getSimOperator(int paramInt);// 服务商(电信、移动、联通)  
  22.   
  23.     protected abstract Object getITelephonyMSim(int paramInt);// 获取操作接口  
  24.   
  25.     protected abstract Object getMSimTelephonyManager(int paramInt);// 获取操作接口  
  26.   
  27. }  


现在列举一款实现MTK方案:

 

 

[cpp] view plaincopy
 
  1. public class MTKDualSim extends AbsSim {// 采用MTK方案的类(根据厂家SDK实现不同的接口)  
  2.     private Object mMSimTelephonyManager = null;  
  3.     private Object mTelephonyMSim = null;  
  4.   
  5.     public MTKDualSim() {  
  6.         mCallLogExtraField = "simid";  
  7.   
  8.         String str1 = SimManager.getModel();  
  9.         String str2 = SimManager.getManufaturer();  
  10.         if ((str1 != null) && (str2 != null)) {  
  11.             String str3 = str1.toLowerCase();  
  12.             String str4 = str2.toLowerCase();  
  13.             if ((str4.indexOf("huawei") > -1) && (str3.indexOf("h30-t00") > -1))  
  14.                 mCallLogExtraField = "subscription";  
  15.             if ((str4.indexOf("hisense") > -1)  
  16.                     && (str3.indexOf("hs-u970") > -1)) {  
  17.                 mCallLogExtraField = "subtype";  
  18.             }  
  19.         }  
  20.     }  
  21.   
  22.     @Override  
  23.     public boolean directCall(String paramString, int paramInt) {  
  24. <span style="white-space:pre">      </span>……  
  25.         return false;  
  26.     }  
  27.   
  28.     @Override  
  29.     public AbsSim detect() {  
  30.         return super.detect();  
  31.     }  
  32.   
  33.     @Override  
  34.     public String getSimPhoneNumber(int paramInt) {  
  35.         return "";  
  36.     }  
  37.   
  38.     @Override  
  39.     public int getDataState(int paramInt) {  
  40.         return -1;  
  41.     }  
  42.   
  43.     @Override  
  44.     public String getIMSI(int paramInt) {  
  45.         return getIMSI(paramInt, null);  
  46.     }  
  47.   
  48.     @Override  
  49.     public String getIMSI(int paramInt, Context paramContext) {  
  50.         return null;  
  51.     }  
  52.   
  53.     @Override  
  54.     public int getPhoneState(int paramInt) {  
  55.         return 0;  
  56.     }  
  57.   
  58.     @Override  
  59.     public boolean isServiceAvaliable(int paramInt) {  
  60.         return false;  
  61.     }  
  62.   
  63.     @Override  
  64.     public boolean isSimStateIsReady(int paramInt) {  
  65.         return false;  
  66.     }  
  67.   
  68.     @Override  
  69.     public int getSimOperator(int paramInt) { // 注意  
  70.         return 0;  
  71.     }  
  72.   
  73.     @Override  
  74.     protected Object getITelephonyMSim(int paramInt) {  
  75.         if (mTelephonyMSim == null)  
  76.             mTelephonyMSim = ITelephony.Stub.asInterface(ServiceManager  
  77.                     .getService("phone"));  
  78.         return mTelephonyMSim;  
  79.     }  
  80.   
  81.     @Override  
  82.     protected Object getMSimTelephonyManager(int paramInt) {  
  83.         return null;  
  84.     }  
  85. }  


再列举一款单卡的方案:

 

 

[cpp] view plaincopy
 
  1. public class SingleSim extends AbsSim implements IDualDetector {// 单卡方案  
  2.     private final String TAG = getClass().getSimpleName();  
  3.     private HashMap<String, Byte> mCallLogExtraFields = new SingleSim$1(this);  
  4.   
  5.     @Override  
  6.     public boolean hasSimPhone() {  
  7.         return false;  
  8.     }  
  9.   
  10.     @Override  
  11.     public AbsSim detect() {// 根据某些字段判是否为双卡(有可能误判)  
  12.         return this;  
  13.     }  
  14.   
  15.     @Override  
  16.     public boolean isDualSimPhone() {  
  17.         return mIsDualSimPhone;  
  18.     }  
  19.   
  20.     @Override  
  21.     public int getSimSlotNum() {  
  22.         return 1;  
  23.     }  
  24.   
  25.     @Override  
  26.     public String getSimPhoneNumber(int paramInt) {  
  27.         return ((TelephonyManager) getMSimTelephonyManager(0)).getLine1Number();  
  28.     }  
  29.   
  30.     @Override  
  31.     public int getDataState(int paramInt) {  
  32.         return ((TelephonyManager) getMSimTelephonyManager(0)).getDataState();  
  33.     }  
  34.   
  35.     @Override  
  36.     public String getIMSI(int paramInt) {  
  37.         return ((TelephonyManager) getMSimTelephonyManager(0)).getDeviceId();  
  38.     }  
  39.   
  40.     @Override  
  41.     public String getIMSI(int paramInt, Context paramContext) {  
  42.         return ((TelephonyManager) getMSimTelephonyManager(0))  
  43.                 .getSubscriberId();  
  44.     }  
  45.   
  46.     @Override  
  47.     public int getPhoneState(int paramInt) {  
  48.         return ((TelephonyManager) getMSimTelephonyManager(0)).getCallState();  
  49.     }  
  50.   
  51.     @Override  
  52.     public boolean isServiceAvaliable(int paramInt) {  
  53.         return false;  
  54.     }  
  55.   
  56.     @Override  
  57.     public boolean isSimStateIsReady(int paramInt) {  
  58.         return ((TelephonyManager) getMSimTelephonyManager(0)).getSimState() == 5;  
  59.     }  
  60.   
  61.     @Override  
  62.     public int getSimOperator(int paramInt) {  
  63.         TelephonyManager localTelephonyManager = (TelephonyManager) getMSimTelephonyManager(paramInt);  
  64.         return Integer.parseInt(localTelephonyManager.getSimOperator());  
  65.     }  
  66.   
  67.     @Override  
  68.     protected Object getITelephonyMSim(int paramInt) {  
  69.         return SimManager.getInstance().getITelephonyByPhone();  
  70.     }  
  71.   
  72.     @Override  
  73.     protected Object getMSimTelephonyManager(int paramInt) {  
  74.         return SimManager.getInstance().getTelephonyManagerByPhone();  
  75.     }  
  76. }  

 

总结

 

利用java 反射机制操作Android隐藏的类,很好的解决了双卡双待的问题。
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。

 

项目下载

 

转: http://blog.csdn.net/banketree/article/details/24306493

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。