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

Android Management API部分设备无法获取serialNumber问题求助

设备序列号获取失败的排查与解决方案

问题背景

使用Android Management API获取设备序列号时,部分机型(如Samsung A30、Samsung Active Tab 3)可正常返回,但Redmi Pro 10、Samsung SM-G781B等机型无法获取,已配置管理应用策略、Manifest权限及相关读取代码。

权限配置修正

1. 补全管理应用策略中的权限授权

当前策略未包含读取设备状态的核心权限,需更新为:

{
    "installType": "REQUIRED_FOR_SETUP",
    "permissionGrants": [
        {
            "policy": "GRANT",
            "permission": "android.permission.PACKAGE_USAGE_STATS"
        },
        {
            "policy": "GRANT",
            "permission": "android.permission.READ_PHONE_STATE"
        },
        {
            "policy": "GRANT",
            "permission": "android.permission.READ_PRIVILEGED_PHONE_STATE"
        }
    ],
    "autoUpdateMode": "AUTO_UPDATE_HIGH_PRIORITY",
    "defaultPermissionPolicy": "GRANT",
    "packageName": "com.example.management",
    "delegatedScopes": [
        "CERT_INSTALL"
    ]
}

注意:READ_PRIVILEGED_PHONE_STATE属于特权权限,仅系统应用或通过Android Management API部署的设备所有者应用可获取,必须在策略中明确授权。

2. 优化Manifest权限声明

移除冗余的版本限制配置,确保权限声明清晰:

<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission
    android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
    tools:ignore="ProtectedPermissions" />
<uses-permission
    android:name="android.permission.READ_PHONE_STATE" />

代码逻辑修复

1. 补充厂商特定系统属性键

不同厂商的序列号存储属性键存在差异,需增加适配:

fun getDeviceSerial(applicationContext: Context): String {
    var serialNumber: String = ""
    try {
        val c = Class.forName("android.os.SystemProperties")
        val get = c.getMethod("get", String::class.java)

        serialNumber = get.invoke(c, "gsm.sn1") as String
        when (serialNumber) {
            "" -> serialNumber = get.invoke(c, "ril.serialnumber") as String
            "" -> serialNumber = get.invoke(c, "ro.serialno") as String
            "" -> serialNumber = get.invoke(c, "sys.serialnumber") as String
            "" -> serialNumber = get.invoke(c, "ro.boot.serialno") as String // 适配部分三星机型
            "" -> serialNumber = get.invoke(c, "ro.miui.serialnumber") as String // 适配小米机型
        }

        @Suppress("DEPRECATION")
        if (serialNumber.isEmpty()) {
            serialNumber = Build.SERIAL
        }
    } catch (e: Exception) {
        e.printStackTrace()
        serialNumber = ""
    }

    // 处理"unknown"情况
    if (serialNumber == "unknown") {
        try {
            val c = Class.forName("android.os.SystemProperties")
            val get = c.getMethod("get", String::class.java, String::class.java)
            serialNumber = get.invoke(c, "ril.serialnumber", "unknown") as String
        } catch (ignored: Exception) {
            ignored.printStackTrace()
        }
    }

    // Android O+官方API读取
    try {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && serialNumber == "unknown") {
            val hasPhonePerm = ActivityCompat.checkSelfPermission(
                applicationContext,
                Manifest.permission.READ_PHONE_STATE
            ) == PackageManager.PERMISSION_GRANTED
            val hasPrivilegedPerm = ActivityCompat.checkSelfPermission(
                applicationContext,
                Manifest.permission.READ_PRIVILEGED_PHONE_STATE
            ) == PackageManager.PERMISSION_GRANTED
            
            if (hasPhonePerm || hasPrivilegedPerm) {
                serialNumber = Build.getSerial()
            }
        }
    } catch (e: Exception) {
        serialNumber = ""
    }
    return serialNumber
}

2. 修正权限检查逻辑

openTelePhony中错误使用CALL_PHONE权限判断,需替换为设备状态权限:

fun openTelePhony(context: Context?) {
    context?.let {
        var a = ""
        try {
            val hasPhonePerm = ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.READ_PHONE_STATE
            ) == PackageManager.PERMISSION_GRANTED
            val hasPrivilegedPerm = ContextCompat.checkSelfPermission(
                context,
                Manifest.permission.READ_PRIVILEGED_PHONE_STATE
            ) == PackageManager.PERMISSION_GRANTED
            
            a = if (hasPhonePerm || hasPrivilegedPerm) {
                getDeviceSerial(context)
            } else {
                @Suppress("DEPRECATION")
                Build.SERIAL
            }
            System.out.print(a)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

额外排查方向

  • 厂商系统限制:部分小米、三星机型会在系统层面限制序列号读取,需确认设备的企业管理设置或开发者选项中未禁用相关权限。
  • 设备所有者身份:确保管理应用通过Android Management API被设置为设备所有者,非设备所有者应用无法获取特权权限。
  • 系统版本适配:Android 10+对隐私权限管控更严格,需确保所有必要权限均通过管理策略授予,且应用已完成权限初始化。

内容的提问来源于stack exchange,提问作者Suman Neupane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 21:40:26