关于多卡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 设备状态

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

进到TelephonyManagergetLine1Number的方法源码中:

可以看到: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卡的手机号码;

列一下常用方法:

  1. 获取通讯类型:
  2. 获取网络类型:
  3. 获取蜂窝网络运营商:
  4. 运营商网段筛选:

    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, "中国铁通");
        }

 ..........

资源下载:Sim卡工具类

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值