当前位置: 首页 > news >正文

Android 双卡双待识别

简单介绍

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


机制

获取基于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);// 获取操作接口

}

如今列举一款实现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) {
		……
		return false;
	}

	@Override
	public AbsSim detect() {
		return super.detect();
	}

	@Override
	public String getSimPhoneNumber(int paramInt) {
		return "";
	}

	@Override
	public int getDataState(int paramInt) {
		return -1;
	}

	@Override
	public String getIMSI(int paramInt) {
		return getIMSI(paramInt, null);
	}

	@Override
	public String getIMSI(int paramInt, Context paramContext) {
		return null;
	}

	@Override
	public int getPhoneState(int paramInt) {
		return 0;
	}

	@Override
	public boolean isServiceAvaliable(int paramInt) {
		return false;
	}

	@Override
	public boolean isSimStateIsReady(int paramInt) {
		return false;
	}

	@Override
	public int getSimOperator(int paramInt) { // 注意
		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) {
		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() {// 依据某些字段判是否为双卡(有可能误判)
		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) {
		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。


项目下载

相关文章:

  • 房坑
  • 该不该用inline-block取代float? inline和float的区别?
  • hibernate--联合主键--XML
  • 动态素组(ArrayList)
  • cssReset - css初始化
  • KeyMob移动广告聚合平台 开发者赚钱平台
  • Lua非常有用的工具——递归打印表数据
  • C风格字符串
  • UVa 10924-Prime Words
  • linux Shell编程
  • Vue--数据传输
  • CentOS 6.4 yum快速搭建Zabbix 2.2版本(中文)
  • python excel 转 csv
  • Android自定义控件实现简单的轮播图控件
  • 2016.04.22-2016.04.28这周工作时间和内容
  • $translatePartialLoader加载失败及解决方式
  • [deviceone开发]-do_Webview的基本示例
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【剑指offer】让抽象问题具体化
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Facebook AccountKit 接入的坑点
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • JWT究竟是什么呢?
  • Linux链接文件
  • Lsb图片隐写
  • mockjs让前端开发独立于后端
  • SpriteKit 技巧之添加背景图片
  • ViewService——一种保证客户端与服务端同步的方法
  • 复习Javascript专题(四):js中的深浅拷贝
  • 基于MaxCompute打造轻盈的人人车移动端数据平台
  • 简析gRPC client 连接管理
  • 京东美团研发面经
  • 排序(1):冒泡排序
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 新版博客前端前瞻
  • 自动记录MySQL慢查询快照脚本
  • 最近的计划
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • 湖北分布式智能数据采集方法有哪些?
  • ​iOS实时查看App运行日志
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ​香农与信息论三大定律
  • ​虚拟化系列介绍(十)
  • #DBA杂记1
  • #单片机(TB6600驱动42步进电机)
  • $L^p$ 调和函数恒为零
  • (09)Hive——CTE 公共表达式
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (C++17) optional的使用
  • (C++20) consteval立即函数
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (学习日记)2024.01.19