You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android中用Kotlin从SIM卡获取手机号?代码调试求助

如何在Android上用Kotlin获取SIM卡手机号码

首先得说,你遇到的问题其实很常见——SubscriptionInfo.number返回空,大多和运营商是否将手机号码写入SIM卡以及权限配置有关。咱们一步步来解决:

1. 先确认权限是否到位

从Android 6.0(API 23)开始,读取手机号需要动态申请敏感权限,不同版本的权限要求还有点区别:

  • Android 9及以下:需要READ_PHONE_STATE权限
  • Android 10+:需要READ_SMS或者READ_PHONE_NUMBERS权限(READ_PHONE_STATE不再返回手机号相关信息)

首先在AndroidManifest.xml里声明权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />

然后在代码里动态申请权限(以Activity为例):

private val REQUIRED_PERMISSIONS = arrayOf(
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) Manifest.permission.READ_SMS else Manifest.permission.READ_PHONE_STATE
)

private fun checkPermissions() {
    if (REQUIRED_PERMISSIONS.any { ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED }) {
        ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, 1001)
    } else {
        fetchPhoneNumbers()
    }
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == 1001 && grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
        fetchPhoneNumbers()
    } else {
        // 权限被拒绝,提示用户
        Toast.makeText(this, "需要权限才能获取手机号", Toast.LENGTH_SHORT).show()
    }
}

2. 优化获取手机号的代码

你的基础代码没问题,但可以补充更多兼容逻辑,同时要明确:不是所有SIM卡都存储了手机号,如果运营商没写入,任何方法都拿不到。

更新后的fetchPhoneNumbers()方法:

private fun fetchPhoneNumbers() {
    val subscriptionManager = SubscriptionManager.from(this)
    // 检查是否有读取订阅信息的权限(Android 11+需要)
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !subscriptionManager.canReadPhoneNumbers()) {
        Toast.makeText(this, "缺少读取号码权限", Toast.LENGTH_SHORT).show()
        return
    }

    val activeSubscriptions = subscriptionManager.activeSubscriptionInfoList
    for (subscriptionInfo in activeSubscriptions) {
        val number = subscriptionInfo.number
        if (number.isNotEmpty()) {
            Log.e("Test", "Number is $number")
        } else {
            // 尝试用TelephonyManager获取备选
            val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            val line1Number = telephonyManager.line1Number
            Log.e("Test", "Subscription number empty, line1Number: ${line1Number.takeIf { it.isNotEmpty() } ?: "Still empty"}")
        }
    }
}

为什么还是拿不到?

如果权限都给了还是返回空,大概率是这几个原因:

  • 运营商没有将手机号码写入SIM卡(很多虚拟运营商或者老SIM卡会这样)
  • 双卡设备中,其中一张卡未激活或者未写入号码
  • 系统隐私设置限制了应用读取手机号的权限

替代方案

如果必须获取用户手机号,建议用短信验证码的方式,这是最可靠的方法——因为不管SIM卡有没有存号码,只要能接收短信就能验证用户的手机号。

内容的提问来源于stack exchange,提问作者Govind Rastogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:58:33