Android开发的问题 其实很好狠。今天看到一篇解决android 机型 双卡 管理的问题。看到一篇比较好的文章就转载过来了 = =
转载:http://blog.csdn.net/banketree/article/details/24306493
获取基于ITelephony接口实现phone应用中的“phone服务”,通过TelephonyManager接口获取不同的卡(GSMPhone /CDMAPhone)进行不同的操作(拨号、接通、挂断、保持通话等)。
Android平台是一个多样型的平台,不同的手机获取ITelephony接口不同,用一种方法实现双卡双待管理是不可取的。那怎么办呢?只有针对不同的手机分析出一套管理的方案,该方案实现难度大,因为需要各个厂家的SDK的资料。为了实现该功能,笔者做了大量工作,整合各个厂家的SDK的资料。
实现
为了更好的管理双卡双待的问题,新建一个双卡双待模块静态库,其它项目引用便是,项目如图:
效果如图:
小米手机 测试效果
华为手机测试效果
AbsSim是抽象类,负责实现手机操作的类。不同的厂家继承该类实现各自的接口。AbsSim信息如下:
- public abstract class AbsSim implements IDualDetector { //抽象基类
- protected final String TAG = getClass().getSimpleName();
- protected ArrayList<SimSlot> mSimSlots = new ArrayList<SimSlot>();
- protected boolean mIsDualSimPhone = false;
- protected String mCallLogExtraField = "";
- public abstract String getSimPhoneNumber(int paramInt); // 返回手机号码
- public abstract int getDataState(int paramInt);// 返回数据状态
- public abstract String getIMSI(int paramInt);// 返回手机标识
- public abstract String getIMSI(int paramInt, Context paramContext);// 返回手机标识
- public abstract int getPhoneState(int paramInt);// 返回手机状态
- public abstract boolean isServiceAvaliable(int paramInt);// 服务是否可用
- public abstract boolean isSimStateIsReady(int paramInt);// 卡是否在使用
- public abstract int getSimOperator(int paramInt);// 服务商(电信、移动、联通)
- protected abstract Object getITelephonyMSim(int paramInt);// 获取操作接口
- protected abstract Object getMSimTelephonyManager(int paramInt);// 获取操作接口
- @Override
- public AbsSim detect() { // 根据手机信息匹配
- if ((getITelephonyMSim(0) != null) && (getITelephonyMSim(1) != null)
- // && (getmMSimSmsManager(0) != null)
- // && (getmMSimSmsManager(1) != null)
- // && (detectSms(paramContext, paramBoolean))
- // && (detectCallLog(paramContext, paramBoolean))
- )
- return this;
- return null;
- }
- public boolean directCall(String paramString, int paramInt) { // 拨打电话(根据不同卡拨打电话)
- Intent localIntent = new Intent("android.intent.action.CALL",
- Uri.fromParts("tel", paramString, null));
- localIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- getContext().startActivity(localIntent);
- return true;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- return false;
- }
- protected boolean detectCallLog() { // 通过通话记录信息匹配
- return false;
- }
- protected boolean detectSms() {// 通过短信记录信息匹配
- return false;
- }
- protected Context getContext() { // 返回句柄
- return SimManager.getInstance().getContext();
- }
- protected int getSimSlotNum() { // 返回插槽个数(默认2)
- return 2;
- }
- public void init() { // 初始化
- for (int i = 0; i < getSimSlotNum(); i++) {
- try {
- String imsi = getIMSI(i);
- boolean isUsing = isSimStateIsReady(i);
- if (imsi != null || isUsing) {
- if (imsi == null || hasSimSlotByIMSI(imsi))
- continue;
- SimSlot simSlot = new SimSlot();
- mSimSlots.add(simSlot);
- simSlot.setUsing(isUsing);
- simSlot.setIMSI(imsi);
- simSlot.setSimOperator(getSimOperator(i));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- public boolean hasSimPhone() {// 是否有sd卡在使用
- if (mSimSlots.isEmpty())
- return false;
- for (SimSlot simslot : mSimSlots) {
- if (simslot.isUsing())
- return true;
- }
- return false;
- }
- public boolean isDualSimPhone() {// 是否为双卡
- if (getSimSlots().isEmpty() || getSimSlots().size() < 2)
- return false;
- for (SimSlot simSlot : getSimSlots()) {
- if (!simSlot.isUsing())
- return false;
- }
- return true;
- }
- public ArrayList<SimSlot> getSimSlots() { // 返回已确认的卡
- return mSimSlots;
- }
- protected boolean delSimSlotByIMSI(String imsi) { // 删除相同的卡的信息
- for (SimSlot simSlot : getSimSlots()) {
- if (simSlot.getIMSI() != null && simSlot.getIMSI().equals(imsi)) {
- getSimSlots().remove(simSlot);
- }
- }
- return false;
- }
- protected boolean hasSimSlotByIMSI(String imsi) {
- for (SimSlot simSlot : getSimSlots()) {
- if (simSlot.getIMSI() != null && simSlot.getIMSI().equals(imsi)) {
- return true;
- }
- }
- return false;
- }
- }
现在列举一款实现MTK方案:
- public class MTKDualSim extends AbsSim {// 采用MTK方案的类(根据厂家SDK实现不同的接口)
- private Object mMSimTelephonyManager = null;
- private Object mTelephonyMSim = null;
- public MTKDualSim() {
- mCallLogExtraField = "simid";
- String str1 = SimManager.getModel();
- String str2 = SimManager.getManufaturer();
- if ((str1 != null) && (str2 != null)) {
- String str3 = str1.toLowerCase();
- String str4 = str2.toLowerCase();
- if ((str4.indexOf("huawei") > -1) && (str3.indexOf("h30-t00") > -1))
- mCallLogExtraField = "subscription";
- if ((str4.indexOf("hisense") > -1)
- && (str3.indexOf("hs-u970") > -1)) {
- mCallLogExtraField = "subtype";
- }
- }
- }
- @Override
- public boolean directCall(String paramString, int paramInt) {
- if (SimManager.isSDKVersionMore4_1()) {
- Intent localIntent1 = new Intent("android.intent.action.CALL",
- Uri.fromParts("tel", paramString, null));
- localIntent1.putExtra("simId", paramInt);
- localIntent1.putExtra("com.android.phone.extra.slot", paramInt);
- localIntent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- getContext().startActivity(localIntent1);
- return true;
- } catch (Throwable localThrowable1) {
- localThrowable1.printStackTrace();
- }
- } else if (SimManager.isSDKVersionMore4_0()) {
- Intent localIntent2 = new Intent(
- "com.android.phone.OutgoingCallReceiver");
- localIntent2.putExtra("com.android.phone.extra.slot", paramInt);
- localIntent2.putExtra("simId", paramInt);
- localIntent2.putExtra("com.android.phone.force.slot", true);
- localIntent2.setClassName("com.android.phone",
- "com.android.phone.OutgoingCallReceiver");
- localIntent2.setData(Uri.fromParts("tel", paramString, null));
- try {
- getContext().sendBroadcast(localIntent2);
- return true;
- } catch (Throwable localThrowable2) {
- localThrowable2.printStackTrace();
- }
- }
- try {
- Intent localIntent3 = new Intent();
- localIntent3.setAction("out_going_call_to_phone_app");
- localIntent3.putExtra("number", paramString);
- localIntent3.putExtra("simId", paramInt);
- localIntent3.putExtra("com.android.phone.extra.slot", paramInt);
- localIntent3.putExtra("launch_from_dialer", 1);
- localIntent3.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- getContext().sendBroadcast(localIntent3);
- return true;
- } catch (Throwable localThrowable3) {
- localThrowable3.printStackTrace();
- }
- return false;
- }
- @Override
- public AbsSim detect() {
- String imsi = getIMSI(0);
- if (imsi != null && !TextUtils.isEmpty(imsi)) {
- return this;
- }
- return super.detect();
- }
- @Override
- public String getSimPhoneNumber(int paramInt) {
- Object[] arrayOfObject2 = new Object[1];
- try {
- Object localObject = getMSimTelephonyManager(paramInt);
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- String result = (String) ReflecterHelper.invokeMethod(localObject,
- "getLine1NumberGemini", arrayOfObject2);
- arrayOfObject2 = null;
- return result;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- return "";
- }
- @Override
- public int getDataState(int paramInt) {
- Object[] arrayOfObject2 = new Object[1];
- try {
- Object localObject = getMSimTelephonyManager(paramInt);
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- int result = ((Integer) ReflecterHelper.invokeMethod(localObject,
- "getDataStateGemini", arrayOfObject2)).intValue();
- arrayOfObject2 = null;
- return result;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- return -1;
- }
- @Override
- public String getIMSI(int paramInt) {
- return getIMSI(paramInt, null);
- }
- @Override
- public String getIMSI(int paramInt, Context paramContext) {
- Object localObject = getMSimTelephonyManager(paramInt);
- Object[] arrayOfObject2 = new Object[1];
- try {
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- String result = (String) ReflecterHelper.invokeMethod(localObject,
- "getSubscriberIdGemini", arrayOfObject2);
- arrayOfObject2 = null;
- return result;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- return null;
- }
- @Override
- public int getPhoneState(int paramInt) {
- Object localObject = getMSimTelephonyManager(paramInt);
- Object[] arrayOfObject2 = new Object[1];
- try {
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- int result = ((Integer) ReflecterHelper.invokeMethod(localObject,
- "getCallStateGemini", arrayOfObject2)).intValue();
- arrayOfObject2 = null;
- return result;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- return 0;
- }
- @Override
- public boolean isServiceAvaliable(int paramInt) {
- Object localObject = getITelephonyMSim(paramInt);
- if (localObject == null)
- return false;
- Object[] arrayOfObject2 = new Object[1];
- try {
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- boolean result = ((Boolean) ReflecterHelper.invokeMethod(
- localObject, "isRadioOnGemini", arrayOfObject2))
- .booleanValue();
- arrayOfObject2 = null;
- return result;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- return false;
- }
- @Override
- public boolean isSimStateIsReady(int paramInt) {
- Object localObject = getMSimTelephonyManager(paramInt);
- if (localObject != null) {
- Object[] arrayOfObject2 = new Object[1];
- try {
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- int result = ((Integer) ReflecterHelper.invokeMethod(
- localObject, "getSimStateGemini", arrayOfObject2))
- .intValue();
- arrayOfObject2 = null;
- return result == 5;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- }
- return false;
- }
- @Override
- public int getSimOperator(int paramInt) { // 注意
- Object localObject = getMSimTelephonyManager(paramInt);
- Object[] arrayOfObject2 = new Object[1];
- try {
- arrayOfObject2[0] = Integer.valueOf(paramInt);
- String result = ((String) ReflecterHelper.invokeMethod(localObject,
- "getSimOperatorGemini", arrayOfObject2));
- arrayOfObject2 = null;
- return Integer.valueOf(result);
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- arrayOfObject2 = null;
- return 0;
- }
- @Override
- protected Object getITelephonyMSim(int paramInt) {
- if (mTelephonyMSim == null)
- mTelephonyMSim = ITelephony.Stub.asInterface(ServiceManager
- .getService("phone"));
- return mTelephonyMSim;
- }
- @Override
- protected Object getMSimTelephonyManager(int paramInt) {
- if (mMSimTelephonyManager != null)
- return mMSimTelephonyManager;
- Object[] arrayOfObject3 = new Object[1];
- try {
- mMSimTelephonyManager = SimManager.getInstance()
- .getTelephonyManagerByPhone();
- try {
- Object localObject = mMSimTelephonyManager;
- arrayOfObject3[0] = Integer.valueOf(0);
- ReflecterHelper.invokeMethod(localObject,
- "getSubscriberIdGemini", arrayOfObject3);
- arrayOfObject3 = null;
- return mMSimTelephonyManager;
- } catch (Throwable localThrowable2) {
- localThrowable2.printStackTrace();
- }
- } catch (Throwable localThrowable1) {
- localThrowable1.printStackTrace();
- }
- arrayOfObject3 = null;
- return null;
- }
- }
再列举一款单卡的方案:
- public class SingleSim extends AbsSim implements IDualDetector {// 单卡方案
- private final String TAG = getClass().getSimpleName();
- private HashMap<String, Byte> mCallLogExtraFields = new SingleSim$1(this);
- @Override
- public boolean hasSimPhone() {
- return false;
- }
- @Override
- public AbsSim detect() {// 根据某些字段判是否为双卡(有可能误判)
- if (mIsDualSimPhone)
- return null;
- Cursor localSafeCursor = null;
- String[] arrayOfString;
- try {
- localSafeCursor = SimManager
- .getInstance()
- .getContext()
- .getContentResolver()
- .query(CallLog.Calls.CONTENT_URI, null, null, null,
- "_id limit 0,1");
- if (localSafeCursor != null && localSafeCursor.moveToFirst()) {
- arrayOfString = localSafeCursor.getColumnNames();
- for (int i = 0; i < arrayOfString.length; i++) {
- String str = arrayOfString[i];
- if (mCallLogExtraFields.containsKey(str.toLowerCase())) {
- mIsDualSimPhone = true;
- mCallLogExtraField = str;
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return this;
- }
- @Override
- public boolean isDualSimPhone() {
- return mIsDualSimPhone;
- }
- @Override
- public int getSimSlotNum() {
- return 1;
- }
- @Override
- public String getSimPhoneNumber(int paramInt) {
- return ((TelephonyManager) getMSimTelephonyManager(0)).getLine1Number();
- }
- @Override
- public int getDataState(int paramInt) {
- return ((TelephonyManager) getMSimTelephonyManager(0)).getDataState();
- }
- @Override
- public String getIMSI(int paramInt) {
- return ((TelephonyManager) getMSimTelephonyManager(0)).getDeviceId();
- }
- @Override
- public String getIMSI(int paramInt, Context paramContext) {
- return ((TelephonyManager) getMSimTelephonyManager(0))
- .getSubscriberId();
- }
- @Override
- public int getPhoneState(int paramInt) {
- return ((TelephonyManager) getMSimTelephonyManager(0)).getCallState();
- }
- @Override
- public boolean isServiceAvaliable(int paramInt) {
- ITelephony localITelephony = (ITelephony) getITelephonyMSim(0);
- if (localITelephony == null)
- return false;
- try {
- boolean bool = localITelephony.isRadioOn();
- return bool;
- } catch (Throwable localThrowable) {
- localThrowable.printStackTrace();
- }
- return false;
- }
- @Override
- public boolean isSimStateIsReady(int paramInt) {
- return ((TelephonyManager) getMSimTelephonyManager(0)).getSimState() == 5;
- }
- @Override
- public int getSimOperator(int paramInt) {
- TelephonyManager localTelephonyManager = (TelephonyManager) getMSimTelephonyManager(paramInt);
- return Integer.parseInt(localTelephonyManager.getSimOperator());
- }
- @Override
- protected Object getITelephonyMSim(int paramInt) {
- return SimManager.getInstance().getITelephonyByPhone();
- }
- @Override
- protected Object getMSimTelephonyManager(int paramInt) {
- return SimManager.getInstance().getTelephonyManagerByPhone();
- }
- }
总结
利用java 反射机制操作Android隐藏的类,很好的解决了双卡双待的问题。
Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。
项目下载