一、需求背景与实现原理
在Android系统定制开发中,彻底禁用SIM卡功能是某些行业设备(如安全终端、Kiosk模式设备)的常见需求。不同于常规的SIM卡状态管理,该功能需要实现:
-
硬件级禁用 - 即使插入SIM卡也无法识别
-
系统级管控 - 防止用户通过设置界面重新启用
-
持久化生效 - 设备重启后策略依然有效
本文基于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层 |
持久化存储 | 需额外处理 | 可集成到系统配置 |
五、实现效果验证
-
射频状态检查
shell
复制
adb shell dumpsys telephony.registry | grep "mRadioState" # 预期输出:mRadioState=0 (RADIO_UNAVAILABLE)
-
基带日志监控
shell
复制
adb logcat -b radio | grep "RILJ" # 预期出现:SET_RADIO_POWER: off
-
API层验证
java
复制
TelephonyManager tm = getSystemService(TelephonyManager.class); tm.getSimState(); // 应返回SIM_STATE_ABSENT tm.isDataEnabled(); // 应返回false
六、注意事项
-
权限声明:需声明系统签名权限
xml
复制
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/> <uses-permission android:name="android.permission.CONTROL_DEVICE_POWER"/>
运行 HTML
-
厂商适配:部分设备需修改RIL层
c
复制
// hardware/ril/reference-ril/ril.cpp static void onRequestShutdown(int request) { RIL_onRequestComplete(request, RIL_E_SUCCESS, NULL, 0); }
-
状态持久化:建议结合DevicePolicyManager实现企业级管控
通过深度定制Android Framework层,开发者可以实现硬件级的SIM卡禁用功能。本文提供的两种方案可根据具体需求选择实现,建议在系统级定制项目中优先采用PhoneWindowManager方案,以确保持久生效与深度管控。
转载请注明出处深度解析 | Android 12系统级禁用SIM卡功能实现与Framework层定制-CSDN博客,谢谢!