You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android 10设备所有者应用调用getDeviceID()获取IMEI失败咨询

为什么设了设备所有者还是拿不到IMEI?

我来帮你拆解这个问题——我之前也帮不少企业用户处理过类似的设备追踪需求,你的情况其实是Android 10+权限体系收紧后的典型问题,核心原因有两个:

  • Android 10+的标识符权限彻底收紧:谷歌从API 29开始,把IMEI、MEID这类电话标识符的访问权限锁得非常死。哪怕你是设备所有者,只要你的应用不是系统级应用或者没有拿到READ_PRIVILEGED_PHONE_STATE这个特权权限,调用getDeviceId()就会抛出SecurityException。设备所有者权限主要管的是设备管理能力(比如强制安装应用、锁屏、限制系统设置),和访问敏感硬件标识符的权限是完全分开的两个体系,不能混为一谈。
  • 你的应用身份还是普通第三方应用:通过adb shell dpm set-device-owner com.package.name/.MyDeviceAdminReceiver设置的设备所有者,本质上还是一个普通的第三方应用(除非你把它放到系统目录并签名),并没有自动获得READ_PRIVILEGED_PHONE_STATE权限——这个权限只有系统预装的应用或者和厂商有合作的应用才能拿到,普通用户通过adb是无法直接赋予的。
可行的IMEI/设备标识符获取方案

根据你的批量设备管理需求,给你三个实用方案:

  • 方案1:用设备序列号替代IMEI(推荐)
    Android 10+明确允许设备所有者应用通过Build.getSerial()获取设备序列号,这个标识符也是唯一的,完全可以满足设备追踪的需求,而且不需要任何额外权限。调用代码很简单:

    String serialNumber = Build.getSerial();
    

    补充:如果你的设备包含Android 8.0以下的版本,Build.getSerial()可能需要READ_PHONE_STATE权限,但你针对的是Android 10+设备,所以直接用就行。

  • 方案2:将应用转为系统级应用(仅当必须要IMEI时)
    如果你的业务逻辑必须依赖IMEI,那只能把应用变成系统应用,步骤如下:

    1. 获取设备的Root权限,或者联系设备厂商将你的应用预装到/system/priv-app目录下;
    2. 用设备厂商的系统签名对APK进行签名;
    3. 在AndroidManifest.xml中声明特权权限:
      <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
      

    这样处理后,你的应用作为系统级设备所有者,就能正常调用getDeviceId()获取IMEI了。不过这个方案门槛较高,需要Root或者厂商配合。

  • 方案3:利用EMM平台的API(适合大规模设备管理)
    如果你是管理大量企业设备,更推荐使用官方的EMM(企业移动管理)框架。EMM平台可以通过设备管理API直接获取IMEI,不需要你的应用自己调用敏感接口。这种方式更适合批量设备的统一管理,而且符合谷歌的权限规范。

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

火山引擎 最新活动