深度解析 | 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博客,谢谢!

相关推荐
红宝村村长1 分钟前
Golang交叉编译到Android上运行
android·开发语言·golang
游戏开发爱好者814 分钟前
iOS 开发推送功能全流程详解 从 APNs 配置到上架发布的完整实践(含跨平台上传方案)
android·macos·ios·小程序·uni-app·cocoa·iphone
恋猫de小郭1 小时前
iOS 26 开始强制 UIScene ,你的 Flutter 插件准备好迁移支持了吗?
android·前端·flutter
杨筱毅1 小时前
【底层机制】【Android】【面试】Zygote 为什么使用 Socket 而不是 Binder?
android·1024程序员节·底层机制
快乐1011 小时前
Media3 ExoPlayer扩展FFmpeg音视频解码
android
zgyhc20502 小时前
【Android Audio】安卓音频中Surround mode切换流程
android·音视频
gfdgd xi3 小时前
Wine运行器3.4.0——虚拟机安装工具支持设置UEFI启动
android·windows·python·ubuntu·架构
shaominjin1234 小时前
OpenCV 4.1.2 SDK 静态库作用与功能详解
android·c++·人工智能·opencv·计算机视觉·中间件
东坡肘子5 小时前
Swift 官方发布 Android SDK | 肘子的 Swift 周报 #0108
android·swiftui·swift
Storm-Shadow12 小时前
Android OpenGLES视频剪辑示例源码
android·opengles·视频滤镜