我想办联通 主副卡 停办了吗能同时接收到主卡的来电和信息吗

1871人阅读
近期公司下发了新任务,需要对Android手机进行双sim卡的管控,而这个功能的关键在于的准确的获取sim卡的SubscriberId值,做过sim卡相关或者电话功能的工程师会很清楚,Android SDK提供了一个方法来获取sim卡的getSubscriberId值。可是这只能获取其中主卡的id值,而副卡根本没有提供API,而且国内的手机大多是双卡手机,所以笔者花了很大功夫调研了大部分市场的畅销Android手机的双卡功能。
整个功能比较繁琐,所以一共分上下两部分讲述。上部讲述市场上主流手机获取副卡Id的方法,以及遇到的困难,注意事项;下部讲述如何整合所有的方案,实现机型自适配,提供一个稳定的API,供其他程序使用。
原生的Android是不支持双卡双待功能的,所以Android sdk没有提供API,直到在Android6.0+上增加了相关的API,但是国内的android嘛,有6.0和没6.0没啥区别,碎片化导致只能利用另外一种方法去获取了—反射。关于反射相关的知识,这里就不进行讲解了,因为获取副卡id会用到大量的反射,不懂的读者可以学习这篇博文[。]
先说说最困难的地方吧,国内的双卡功能是由厂商联合芯片开发商定做的,所以芯片商不一样,厂商不一样,实现方案也就不一样,所以反射的类和函数名也不一样。总的来说,目前全球有高通(小米),联发科(魅族),麒麟海思(华为),猎户座(三星)四家移动通讯芯片制造商,笔者通过一周的时间,将公司的所有测试机进行了反射获取,终于总结出了如下方案:
代表手机:小米,vivo,oppo
反射的类:TelephonyManager
反射方法:getSubscriberId(int id)
反射方法:getSubscriberId(long id)
高通系手机获取副卡的API还算规范化,直接在android的原生类中添加了方法,而android6.0+提供的官方双卡API也是这样做的。android提供获取simid原生单卡API为:
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String id = telephonyManager.getSubscriberId();
所以使用部分厂商直接在TelephonyManager类中重载了该方法, 不过厂商的重载的参数不同,比如笔者在进开发时发现,小米,红米系列使用的重载方法为getSubscriberId(int id),而vivo,oppo,中兴则使用getSubscriberId(long id),反射的代码如下:
public int getSecondImsi(Context context) throws InvocationTargetException,IllegalAccessException, NoSuchMethodException {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Class&?& telephonyclass = telephonyManager.getClass();
Method method = null;
boolean param = true;
method = telephonyclass.getDeclaredMethod("getSubscriberId",int.class);
}catch (NoSuchMethodException e){
method = telephonyclass.getDeclaredMethod("getSubscriberId",long.class);
param = false;
}catch (NoSuchMethodException e2) {
Object object = null;
HashSet&String& buildSet = new HashSet&&();
if (param){
for(int i = 0;i & 9;i++) {
object = method.invoke(telephonyManager,i);
if (object != null){
buildSet.add(object.toString());
这里需要做几点说明:
1.反射需要抛出几种异常情况如:
NoSuchMethodException: 没有这个函数
IllegalAccessException:此方法为私有方法,不能反射
InvocationTargetException:反射方法内部出现异常
ClassNotFoundException:没有这个类,在华为系手机中会用到
2.使用HashSet保存结果,这里使用set保存结果的原因有2点
第一是因为厂商问题,系统不会给你准确的返回卡槽1或者卡槽2的值,而是一旦判定卡槽里有卡就会返回,比如,一张卡插在任意一个卡槽中,通过系统API都能返回SIMid。所以,在插入双卡的情况下,通过反射可能会获取到所有的值,我们没有办法根据卡槽来获取值,保证卡与卡槽的一一对应。这样只能采用set的唯一性来保证获取到所有的值。
第二还是因为厂商原因,笔者在开发时发现,通过反射getSubscriberId(long id)方法,这里的参数id没有任何可参考性,当初以为可以输入0,1就能返回不同的simid,结果是输入5才能获取另一个simid……而且,就拿vivo的一款旗舰机而言,输入从1-9,只有输入5才获取到副卡的id,其他返回的都是主卡的id,这就很坑了,所有笔者简单粗暴的使用for循环,不管有没有值,都存到set里,性能会影响,但保证功能。总结一句话,厂商提供的getSubscriberId(long id)方法的id没有参考意义,直接简单粗暴的循环,这也导致了笔者实现的此功能的缺陷:只能获取到simid,没有办法保证卡与卡槽的一一对应
代表手机:华为荣耀系列,P系列,mate系列
反射类:”android.telephony.MSimTelephonyManager”
反射方法:getSubscriberId(int id)
反射方法:getSubscriberId(long id)
华为系手机比较复杂,因为和自身的芯片有关系,比如,大部分华为高端机型使用了自身的芯片,第二张sim卡的相关API封装在android.telephony.MSimTelephonyManager这个类,而部分采用高通机型的华为手机还是使用高通方案。比如华为P7,P8,P9用了自身方案,而MATE8采用了高通方案,笔者在后期适配时被整的很惨……
要反射华为系手机的MSimTelephonyManager类的方法如下:
protected int getassistantImsi(Context context) throws IllegalAccessException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
Class&?& telephonyClass = Class.forName("android.telephony.MSimTelephonyManager");
Method getdefault = telephonyClass.getMethod("getDefault");
Object telephonyManager = getdefault.invoke(null);
Method method = null;
boolean param = true;
method = telephonyClass.getMethod("getSubscriberId", int.class);
} catch (NoSuchMethodException e) {
method = telephonyClass.getMethod("getSubscriberId", long.class);
param = false;
} catch (NoSuchMethodException e2) {
return NO_SUCH_METHOD;
Object object = null;
HashSet&String& buildSet = new HashSet&&();
if (param) {
for (int i = 0; i & 9; i++) {
object = method.invoke(telephonyManager, i);
if (object != null) {
buildSet.add(object.toString());
for (long i = 0; i & 9; i++) {
object = method.invoke(telephonyManager, i);
if (object != null) {
buildSet.add(object.toString());
return SUCCESS;
代码与上文中高通系手机反射方案差不多,不同的是增加了一个反射类的处理
Class&?& telephonyClass = Class.forName("android.telephony.MSimTelephonyManager");
Method getdefault = telephonyClass.getMethod("getDefault");
Object telephonyManager = getdefault.invoke(null);
Method method = null;
这样我们就能获取到类的实例,然后反射去执行就行了,其他操作如上文。
代表手机:note2,3,s4
反射类:无
反射方法:无
早期的三星系使用的是自家的方案,如note2,3,s4等,三星也和华为一样,另外封装了一个类来管理副卡,而近期的高端机型貌似使用了android原生双卡管理,就是高通方案。
代码如下:
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService("phone2")
telephonyManager.getSubscriberId()
个人觉得另外封装一个类是比较好的处理……
联发科系:
代表手机:魅族
反射类:TelephonyManager
反射方法:getSubscriberIdGemini()
反射方案和高通类似,就是反射的方法不同,这里就不贴代码了……
其他手机:
其他手机反射方案也不写了,因为笔者找遍公司所有测试机,没有找到这些山寨机
不过要适配这些机型的,可以这个博文
这是笔者第一次写博文,所以写的不好请多包含,有什么问题或者错误请指正,互相进步嘛。
欢迎转载,请指明出处。
关于双卡功能的管理,本文只是对市场上android手机双卡的一次普查,以及方案的提供。目前是市场上存在的机型大多使用这些方法,而且网上也有很多相关博客。所以如何适配机型,根据机型来选择正确的方案,这才是实现的难点。采用人为枚举是一个很傻叉的行为(因为笔者早期的方案就是枚举所有机型),适配的工作,应该交给软件自身来做。所以,下一篇博文会讲述如何整和这些方案,让程序自行进行适配,选择合适的方案获取simid。相关代码会在下一博文中提供开源地址。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1986次
排名:千里之外
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'不安主卡只安副卡可以打电话吗?_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
不安主卡只安副卡可以打电话吗?
我有更好的答案
随便哪个卡槽装上都可以使用。希望回答对你有帮助。例如电信4G手机就不支持移动4G卡。当然必须是手机支持的卡可以的。手机支持双卡的话
采纳率:89%
为您推荐:
其他类似问题
打电话的相关知识
等待您来回答}

我要回帖

更多关于 电信主副卡 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信