栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

关于多卡Android设备获取手机号的研究

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

关于多卡Android设备获取手机号的研究

首先我们都知道如何获取Android手机的Sim手机号

fun getNativePhoneNumber(context: Context): String? {
        
    val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    return  tm.line1Number
}

获取到 TelephonyManager 对象,通过调用 getLine1Number方法就可以获取到手机号;

注意:提前获取权限:

Manifest.permission.READ_PHONE_STATE: android 设备状态

那么获取双卡设备的第二张卡的手机号怎么办呢?

进到TelephonyManager的getLine1Number的方法源码中:

 

可以看到:getLine1Number方法是通过其内部的getLine1Number(getSubId)方法实现的,但是这个方法被注解标记:@UnsupportedAppUsage 不可被应用程序调用;

看到这里就会想:通过一个subId 通过getLine1Number方法就可以获取到手机号,而这个id大概率是每一个Sim卡所对应的唯一Id值;

通过反射调用内部getLine1Number(int subId) 方法

这个方法不可被调用,那就试试通过发射能不能调用到这个程序呢:

 通过测试代码测试:发现真的可以通过反射调用到被@UnsupportedAppUsage 标记的方法;

获取subId值

解决了注解方法不可调用的问题,接下来解决获取subId的问题;

从上面的截图可以看到subId是通过一个 getSubId()  方法获取到的;

 注意红框中的类:SubscriptionManager,大胆猜想,subId全称是不是就叫SubscriptionId,毕竟他是通过SubscriptionManager获取到的;

那么可以研究一下这个类:SubscriptionManager

创建方式:
SubscriptionManager subscriptionManager = (SubscriptionManager) context.getSystemService(Context.TELEPHONY_SUBscriptION_SERVICE);

并找到了下图中的方法:

 该方法返回一个SubscriptionInfo列表,并且SubscriptionInfo对象存在一个getSubscriptionId()方法;

 整个流程就是:

1、获取SubscriptionManager,通过其getActiveSubscriptionInfoList()方法获取到SubscriptionInfo列表;

2、遍历SubscriptionInfo列表,通过getSubscriptionId()方法获取获取到id值;

3、获取TelephonyManager类对象,通过反射传入id值;

4、method.invoke(tm, subId)方法的返回值就是手机号码;

End

这样就可以获取到多卡Android设备的所有可用Sim卡的手机号码;

列一下常用方法:

    获取通讯类型:获取网络类型:获取蜂窝网络运营商:

    运营商网段筛选:

    fun from(code: String) = when (code) {
            "46000", "46002", "46004", "46007", "46008" -> Operator.CHINA_MOBILE
            "46001", "46006", "46009" -> Operator.CHINA_UNICOM
            "46003", "46005", "46011" -> Operator.CHINA_TELECOM
            "46020" -> Operator.CHINA_RAILCOM
            else -> Operator.UNKNOWN_OPERATOR
        }
    
        fun fromOpName(name: String) = when (name) {
            "中国移动" -> Operator.CHINA_MOBILE
            "中国联通" -> Operator.CHINA_UNICOM
            "中国电信" -> Operator.CHINA_TELECOM
            "中国铁通" -> Operator.CHINA_RAILCOM
            else -> Operator.UNKNOWN_OPERATOR
        }
    
        enum class Operator(var type: Int, var operatorName: String) {
            CLOSE_FLOW(-2, "流量数据未打开")
            , NONE_OPERATOR(-1, "无sim卡")
            , UNKNOWN_OPERATOR(0, "其他")
            , CHINA_MOBILE(1, "中国移动")
            , CHINA_UNICOM(2, "中国联通")
            , CHINA_TELECOM(3, "中国电信")
            , CHINA_RAILCOM(4, "中国铁通");
        }

 ..........

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/710019.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号