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

Android使用TelephonyManager获取设备信息触发SecurityException问题求助

问题:Android获取MEID/IMEI时触发SecurityException,UID无访问权限

错误信息

E/SecurityException Error(29502): Security Exception: IMEI access not permitted
E/SecurityException Error(29502): java.lang.SecurityException: getMeidForSlot: The uid 11222 does not meet the requirements to access device identifiers.
E/SecurityException Error(29502):   at android.os.Parcel.createExceptionOrNull(Parcel.java:3023)
E/SecurityException Error(29502):   at android.os.Parcel.createException(Parcel.java:3007)
E/SecurityException Error(29502):   at android.os.Parcel.readException(Parcel.java:2990)
E/SecurityException Error(29502):   at android.os.Parcel.readException(Parcel.java:2932)
E/SecurityException Error(29502):   at com.android.internal.telephony.ITelephony$Stub$Proxy.getMeidForSlot(ITelephony.java:10794)
E/SecurityException Error(29502):   at android.telephony.TelephonyManager.getMeid(TelephonyManager.java:2898)
E/SecurityException Error(29502):   at android.telephony.TelephonyManager.getMeid(TelephonyManager.java:2855)
E/SecurityException Error(29502):   at com.example.sim_iccid_demo.MainActivity.getIccidList(MainActivity.kt:50)
E/SecurityException Error(29502):   at com.example.sim_iccid_demo.MainActivity.configureFlutterEngine$lambda-0(MainActivity.kt:24)
E/SecurityException Error(29502):   at com.example.sim_iccid_demo.MainActivity.$r8$lambda$8Tzl3un6utopCfe_BwLm26cMOFo(Unknown Source:0)
E/SecurityException Error(29502):   at com.example.sim_iccid_demo.MainActivity$$ExternalSyntheticLambda0.onMethodCall(Unknown Source:2)
E/SecurityException Error(29502):   at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:258)
E/SecurityException Error(29502):   at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:295)
E/SecurityException Error(29502):   at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:322)
E/SecurityException Error(29502):   at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
E/SecurityException Error(29502):   at android.os.Handler.handleCallback(Handler.java:942)
E/SecurityException Error(29502):   at android.os.Handler.dispatchMessage(Handler.java:99)
E/SecurityException Error(29502):   at android.os.Looper.loopOnce(Looper.java:226)
E/SecurityException Error(29502):   at android.os.Looper.loop(Looper.java:313)
E/SecurityException Error(29502):   at android.app.ActivityThread.main(ActivityThread.java:8757)
E/SecurityException Error(29502):   at java.lang.reflect.Method.invoke(Native Method)
E/SecurityException Error(29502):   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
E/SecurityException Error(29502):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)

问题背景

开发SIM卡及设备信息相关功能时触发上述错误,该功能在Android 10及以下版本正常运行,但需要适配全版本获取设备信息及ICCID,已按官方要求配置权限。

已配置的权限(AndroidManifest.xml)

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER" />
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

实现代码

private Map<String, String> getSimInfo() {
    Map<String, String> simInfo = new HashMap<>();

    try {
        SubscriptionManager subsManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
        List<SubscriptionInfo> subsList = subsManager.getActiveSubscriptionInfoList();

        if (subsList != null) {
            for (SubscriptionInfo subsInfo : subsList) {
                String iccid = subsInfo.getIccId();
                if (iccid != null) {
                    simInfo.put("ICCID" + subsInfo.getSimSlotIndex(), iccid);
                }
            }
        }

        String androidId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
        simInfo.put("AndroidID", androidId != null ? androidId : "N/A");
        simInfo.put("MEID","N/A");
        simInfo.put("IMEI","N/A");
        
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        String meid = telephonyManager.getSimSerialNumber();
        simInfo.put("MEID", meid != null ? meid : "N/A");
        if (getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_GSM)) {
            try {
                String imei = telephonyManager.getImei();
                Log.d("IMEI DATA", imei);
                simInfo.put("IMEI", imei != null ? imei : "N/A");
            } catch (SecurityException e) {
             handleException("IMEI access not permitted", e);
            }
        }
    } catch (SecurityException e) {
        handleException("IMEI access not permitted", e);
    } catch (Exception e) {
        handleException("An error occurred", e);
    }
    return simInfo;
}

解决方案

核心原因

Android 10(API 29)及以上版本对设备标识符(IMEI/MEID等)做了强制限制:

  • 普通第三方应用无法通过READ_PHONE_STATE获取IMEI/MEID
  • READ_PRIVILEGED_PHONE_STATE仅系统应用或签名级权限应用可使用,普通应用无法获取

针对性修复方案

1. 分版本处理设备标识符获取

Android 10+放弃直接获取IMEI/MEID,改用AndroidID作为替代;仅在Android 9及以下版本尝试获取:

// 修改getSimInfo方法中的设备标识逻辑
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
    // Android 9及以下版本尝试获取MEID/IMEI
    try {
        String meid = telephonyManager.getMeid();
        simInfo.put("MEID", meid != null ? meid : "N/A");
        if (getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_GSM)) {
            String imei = telephonyManager.getImei();
            simInfo.put("IMEI", imei != null ? imei : "N/A");
        }
    } catch (SecurityException e) {
        handleException("设备标识访问被拒绝", e);
    }
} else {
    // Android 10+仅保留AndroidID
    simInfo.put("MEID", "N/A");
    simInfo.put("IMEI", "N/A");
}

2. 清理无效权限

移除普通应用无法使用的权限,避免冗余:

<!-- 移除以下权限 -->
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" />

3. 确保ICCID权限正常

你的ICCID获取逻辑是正确的,Android 10+仍可通过SubscriptionManager获取,但需确保已动态申请READ_PHONE_STATE权限:

// 动态申请权限示例
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 1001);
}

关键注意事项

  • Android 10+普通应用无法获取IMEI/MEID,这是系统强制限制,无绕过方法
  • 若业务需唯一设备标识,优先使用AndroidID或第三方标识方案(如Firebase Instance ID)
  • ICCID获取不受Android 10+严格限制,只要正确申请READ_PHONE_STATE即可正常获取

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:24:53