深度解析 | Android 12系统级禁用SIM卡功能实现与Framework层定制

一、需求背景与实现原理

在Android系统定制开发中,彻底禁用SIM卡功能是某些行业设备(如安全终端、Kiosk模式设备)的常见需求。不同于常规的SIM卡状态管理,该功能需要实现:

  1. 硬件级禁用 - 即使插入SIM卡也无法识别

  2. 系统级管控 - 防止用户通过设置界面重新启用

  3. 持久化生效 - 设备重启后策略依然有效

本文基于Android 12源码,深入分析Framework层实现方案,提供两种核心实现路径:


二、实现方案一:关机流程劫持(ShutdownThread)
1. 核心原理分析

关机流程中的SIM卡关闭逻辑位于ShutdownThread,其调用链为:

复制

复制代码
PowerManager.shutdown() 
→ ShutdownThread.shutdown() 
→ shutdownRadios() 
→ ITelephony.shutdownMobileRadios()

关键代码段:

java

复制

复制代码
// frameworks/base/services/core/java/com/android/server/power/ShutdownThread.java
private void shutdownRadios(final int timeout) {
    final ITelephony phone = ITelephony.Stub.asInterface(
        ServiceManager.checkService("phone"));
    // 核心禁用逻辑
    phone.shutdownMobileRadios(); 
}
2. 改造实现

java

复制

复制代码
public void disableSimPermanently(Context context) {
    final long identity = Binder.clearCallingIdentity();
    try {
        ITelephony telephony = ITelephony.Stub.asInterface(
            ServiceManager.getService(Context.TELEPHONY_SERVICE));
        if (telephony != null) {
            // 强制关闭所有基带模块
            telephony.shutdownMobileRadios();
            // 持久化状态防止重启恢复
            Settings.Global.putInt(context.getContentResolver(),
                "airplane_mode_on", 1); 
        }
    } catch (RemoteException e) {
        Log.e(TAG, "Telephony service unavailable", e);
    } finally {
        Binder.restoreCallingIdentity(identity);
    }
}
3. 方案特点
  • 即时生效:执行后立即禁用

  • 依赖关机流程:需触发关机/重启操作

  • 兼容性风险:不同厂商可能定制Telephony服务


三、实现方案二:系统服务初始化拦截(PhoneWindowManager)
1. 核心原理分析

系统服务初始化阶段调用PhoneWindowManager.systemReady(),通过Phone对象直接操作基带:

java

复制

复制代码
// frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
private void shutdownRadioUsingPhoneId(int phoneId) {
    Phone phone = PhoneFactory.getPhone(phoneId);
    if (phone != null) {
        phone.shutdownRadio(); // 底层调用RIL请求
    }
}
2. 改造实现

java

复制

复制代码
@Override
public void systemReady() {
    // 系统服务初始化完成时执行
    TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
    for (int i = 0; i < tm.getPhoneCount(); i++) {
        Phone phone = PhoneFactory.getPhone(i);
        if (phone != null && phone.isRadioAvailable()) {
            phone.shutdownRadio();
            // 持久化禁用状态
            phone.setRadioPower(false); 
        }
    }
    // 禁用SIM卡相关服务
    disableSimServices(true);
}

private void disableSimServices(boolean disable) {
    PackageManager pm = mContext.getPackageManager();
    ComponentName comp = new ComponentName("com.android.phone", 
        "com.android.phone.TelephonyDebugService");
    pm.setComponentEnabledSetting(comp,
        disable ? PackageManager.COMPONENT_ENABLED_STATE_DISABLED
                : PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
        PackageManager.DONT_KILL_APP);
}
3. 方案特点
  • 启动阶段生效:系统初始化即禁用

  • 深度系统集成:修改Framework核心服务

  • 需处理多SIM卡:遍历PhoneCount


四、技术要点对比
维度 关机流程方案 系统初始化方案
生效时机 关机/重启后生效 系统启动时立即生效
修改风险 较低(流程劫持) 较高(核心服务修改)
多SIM卡支持 自动处理 需遍历Phone对象
OEM兼容性 依赖AOSP实现 需适配厂商RIL层
持久化存储 需额外处理 可集成到系统配置

五、实现效果验证
  1. 射频状态检查

shell

复制

复制代码
adb shell dumpsys telephony.registry | grep "mRadioState"
# 预期输出:mRadioState=0 (RADIO_UNAVAILABLE)
  1. 基带日志监控

shell

复制

复制代码
adb logcat -b radio | grep "RILJ"
# 预期出现:SET_RADIO_POWER: off
  1. API层验证

java

复制

复制代码
TelephonyManager tm = getSystemService(TelephonyManager.class);
tm.getSimState(); // 应返回SIM_STATE_ABSENT
tm.isDataEnabled(); // 应返回false

六、注意事项
  1. 权限声明:需声明系统签名权限

xml

复制

复制代码
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
<uses-permission android:name="android.permission.CONTROL_DEVICE_POWER"/>

运行 HTML

  1. 厂商适配:部分设备需修改RIL层

c

复制

复制代码
// hardware/ril/reference-ril/ril.cpp
static void onRequestShutdown(int request) {
    RIL_onRequestComplete(request, RIL_E_SUCCESS, NULL, 0);
}
  1. 状态持久化:建议结合DevicePolicyManager实现企业级管控

通过深度定制Android Framework层,开发者可以实现硬件级的SIM卡禁用功能。本文提供的两种方案可根据具体需求选择实现,建议在系统级定制项目中优先采用PhoneWindowManager方案,以确保持久生效与深度管控。

转载请注明出处深度解析 | Android 12系统级禁用SIM卡功能实现与Framework层定制-CSDN博客,谢谢!

相关推荐
maki0776 分钟前
虚幻版Pico大空间VR入门教程 05 —— 原点坐标和项目优化技巧整理
android·游戏引擎·vr·虚幻·pico·htc vive·大空间
千里马学框架42 分钟前
音频焦点学习之AudioFocusRequest.Builder类剖析
android·面试·智能手机·车载系统·音视频·安卓framework开发·audio
fundroid4 小时前
掌握 Compose 性能优化三步法
android·android jetpack
TeleostNaCl5 小时前
如何在 IDEA 中使用 Proguard 自动混淆 Gradle 编译的Java 项目
android·java·经验分享·kotlin·gradle·intellij-idea
旷野说6 小时前
Android Studio Narwhal 3 特性
android·ide·android studio
maki07712 小时前
VR大空间资料 01 —— 常用VR框架对比
android·ue5·游戏引擎·vr·虚幻·pico
xhBruce16 小时前
InputReader与InputDispatcher关系 - android-15.0.0_r23
android·ims
领创工作室16 小时前
安卓设备分区作用详解-测试机红米K40
android·java·linux
hello_ludy16 小时前
Android 中的 mk 和 bp 文件编译说明
android·编译
maki07719 小时前
VR大空间资料 03 —— VRGK使用体验和源码分析
android·vr·虚幻·源码分析·oculus·htc vive·vrgk