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

获取Android设备IMEI时触发安全异常的解决方案咨询

问题描述

需要获取Android设备的IMEI号码,应用仅用于企业内部个人使用,不会上架Google Play商店。目前获取IMEI时触发安全异常,已制作设备管理应用,但仍无法访问IMEI,寻求可行解决办法。

现有代码
class MainActivity : AppCompatActivity() {
    val REQUEST_CODE = 101
    var imei: String? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 初始化变量
        val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
        val imeiTextView = findViewById<TextView>(R.id.idTVIMEI)

        // 检查权限
        if (ActivityCompat.checkSelfPermission(
                this,
                Manifest.permission.READ_PHONE_STATE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            // 申请权限
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.READ_PHONE_STATE),
                REQUEST_CODE
            )
        }

        // 将IMEI设置到TextView
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            imei = telephonyManager.imei
        }
        imeiTextView.setText(imei)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String?>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE) {
            // 检查权限是否授予
            if (grantResults.size != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限已授予。", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this, "权限已拒绝。", Toast.LENGTH_SHORT).show()
            }
        }
    }
}
可行解决办法

1. 针对Android版本调整权限策略

  • Android 10(API 29)及以上:READ_PHONE_STATE权限不再允许获取IMEI,除非应用满足以下任一条件:

    • 成为设备所有者应用或配置文件所有者应用:需要通过Android Enterprise的官方方式(如QR码批量配置、NFC触碰绑定、AFW模式)完成设备绑定,普通设备管理应用无法自动获得该权限。绑定成功后,无需申请READ_PHONE_STATE,直接调用TelephonyManager.getImei()即可获取。
    • 拥有READ_PRIVILEGED_PHONE_STATE权限:该权限仅开放给系统应用或OEM签名的应用,适合企业有定制ROM的场景,可联系设备厂商申请权限并签名应用。
  • Android 9(API 28)及以下:确保已在AndroidManifest.xml中声明READ_PHONE_STATE权限,且用户完成授权。同时注意现有代码的逻辑缺陷——申请权限后未等待用户授权就直接获取IMEI,会导致首次启动时触发异常。

2. 修复现有代码的逻辑漏洞

现有代码在权限申请流程中,没有在用户授权后重新获取IMEI,导致首次启动时权限未授予的情况下imei为空甚至触发异常。修改onRequestPermissionsResult方法,补充授权后的IMEI获取逻辑:

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<String?>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_CODE) {
        val telephonyManager = getSystemService(TELEPHONY_SERVICE) as TelephonyManager
        val imeiTextView = findViewById<TextView>(R.id.idTVIMEI)
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "权限已授予。", Toast.LENGTH_SHORT).show()
            // 权限授予后重新获取IMEI
            imei = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                telephonyManager.imei
            } else {
                // Android O以下版本使用deviceId
                telephonyManager.deviceId
            }
            imeiTextView.text = imei
        } else {
            Toast.makeText(this, "权限已拒绝。", Toast.LENGTH_SHORT).show()
        }
    }
}

3. 正确配置设备所有者应用

如果你的设备管理应用未成功成为设备所有者,可通过以下方式完成绑定:

  • 测试设备:使用ADB命令直接设置:dpm set-device-owner com.your.package/.YourDeviceAdminReceiver(替换为你的应用包名和设备管理接收器类名)。
  • 批量设备:生成包含应用下载链接和配置信息的QR码,设备首次启动时扫描即可完成绑定。
  • NFC绑定:通过已配置好设备所有者的设备,触碰目标设备完成快速绑定。

4. 替代标识符方案(无法获取IMEI时)

如果以上方法均无法实现,可考虑使用其他唯一标识替代:

  • Android ID:Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID),注意设备重置或刷机后会改变。
  • 设备序列号:Build.SERIAL(Android 8.0及以上需要READ_PHONE_STATE权限,设备所有者应用可直接获取)。
  • 自定义UUID:应用首次启动时生成UUID并存储在本地SharedPreferences中,适合仅需要应用内唯一标识的场景。

内容的提问来源于stack exchange,提问作者Apurva Jariwala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:31:02