Android 12 Beta环境下无法通过ADB读取IMSI信息,寻求可行替代方案
Android 12+ 无法通过ADB获取IMSI的问题分析与解决方案
首先,你遇到的这个问题完全是Android 12对隐私权限管控进一步收紧导致的——先解码一下你得到的Parcel返回内容,实际是:
getSubscriberIdForSubscriber: Package null does not belong to 2000
这意味着ADB shell(没有对应包名和权限的进程)已经被禁止调用iphonesubinfo服务的这个敏感方法了,而Android 11及之前的版本对这种调用的权限校验没这么严格。
再结合你提到的权限变更:从Android 10开始,普通应用的READ_PHONE_STATE权限就拿不到IMSI了,唯一能读取IMSI的READ_PRIVILEGED_PHONE_STATE权限只对系统签名应用、厂商预装应用或特定企业类应用开放。
下面是几种可行的解决路径,按合规性和可实现性排序:
1. 借助设备所有者/配置文件所有者应用(非Root,合规方案)
如果你的使用场景是企业设备管理,那么可以把你的应用配置为设备所有者或配置文件所有者:
- 在Android 10及以上版本,这类应用可以申请
READ_PRIVILEGED_PHONE_STATE权限,并且能通过企业管理流程获得用户授权。 - 部署方式通常需要通过MDM平台,或者在设备初始化阶段用NFC、二维码等方式设置设备所有者。
- 拿到权限后,直接调用
TelephonyManager.getSubscriberId()就能正常获取IMSI,完全不需要依赖ADB命令。
2. 系统签名应用(需厂商合作)
如果你能和设备厂商达成合作,让你的应用使用系统级签名:
- 系统签名的应用默认拥有
READ_PRIVILEGED_PHONE_STATE权限,直接调用官方API就能拿到IMSI。 - 不过这个方案对普通第三方开发者来说几乎不可行,因为系统签名密钥掌握在厂商手里,只有预装应用才能使用。
3. Root权限(仅测试/个人场景,非合规)
虽然你说不想用Root,但这是普通用户在非企业、非预装场景下唯一的解决办法:
- Root后,你可以直接读取系统数据库文件(比如
/data/user_de/0/com.android.providers.telephony/databases/telephony.db里的相关表)获取IMSI,或者以root身份执行ADB命令绕过权限限制。 - 注意:Root会导致设备失去保修,还会带来安全风险,绝对不建议在生产环境使用。
为什么Android 11及之前能用ADB命令?
Android 12之前,ADB shell的权限管控相对宽松,允许调用iphonesubinfo的敏感方法,但Android 12对Binder服务的访问做了更严格的校验,只有拥有特定权限或系统级UID的进程才能调用这些方法。
总结一下:如果没有厂商合作或企业管理场景的支持,普通第三方应用在Android 12+上确实无法稳定读取IMSI,这是系统隐私保护机制的硬性限制,没有绕开的合规途径。
内容的提问来源于stack exchange,提问作者Soul187




