一、需求背景与实现原理
在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博客,谢谢!