在Android Enterprise或者说Android for Work场景下,受管配置(Managed Configurations)允许IT管理员通过MDM统一下发应用参数。实现这一能力的核心就是app_restrictions.xml文件,它本质上是一个描述应用可配置项结构的schema文件。系统依据该文件生成配置界面,并将管理员填写的值传给应用。

app_restrictions.xml文件的基础结构
该文件必须放置在模块的res/xml/目录下,通常命名为app_restrictions.xml。根节点是restrictions,内部每个配置项用restriction标签描述。每个restriction至少包含key、title和restrictionType三个属性。key是应用读取时的唯一标识,只能用小写字母、数字和下划线;title是MDM控制台展示的名称。
除了基本属性,还可以用default-value指定默认值,用description补充说明。如果类型是多选或单选,需要通过restriction嵌套的entry标签列出可选项。下面是一个最小可用的示例,定义了一个布尔开关和一个字符串输入框。
<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
<restriction
android:key="allow_camera"
android:title="允许使用摄像头"
android:restrictionType="bool"
android:default-value="true" />
<restriction
android:key="server_url"
android:title="服务地址"
android:restrictionType="string"
android:default-value="https://ipipp.com/api" />
</restrictions>
支持的限制类型与写法差异
Android系统支持多种restrictionType,常用的有bool、string、integer、choice、multi-select、bundle和bundle_array。choice用于单选下拉,multi-select用于多选,这两者必须提供entry子节点。bundle类型可以把一组配置聚合在一起,bundle_array则适合配置列表类数据,例如多个WiFi账号。
以下代码展示了choice与multi-select的正确声明方式。注意entry的value是实际传给应用的取值,name是展示文本。如果漏写entry,MDM界面将无法渲染该配置项,导致管理员无法设置。
<restriction
android:key="log_level"
android:title="日志级别"
android:restrictionType="choice"
android:default-value="info">
<entry android:value="debug" android:name="调试" />
<entry android:value="info" android:name="信息" />
<entry android:value="error" android:name="错误" />
</restriction>
<restriction
android:key="enabled_modules"
android:title="启用的模块"
android:restrictionType="multi-select">
<entry android:value="push" android:name="推送" />
<entry android:value="stat" android:name="统计" />
</restriction>
在应用中读取配置并响应变更
配置下发后,应用通过RestrictionsManager读取。调用getApplicationRestrictions()可拿到当前Bundle,按key提取对应类型的值。需要注意的是,首次安装若管理员未下发,返回的是文件中定义的default-value;若连默认值都没写,对应key可能不存在,读取时应做判空。
当MDM更新策略时,系统会发送ACTION_APPLICATION_RESTRICTIONS_CHANGED广播。应用应注册一个监听该动作的BroadcastReceiver,在收到后重新拉取配置并刷新业务状态。下面代码演示了读取与监听的基本写法。
// 读取受管配置
RestrictionsManager rm = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
Bundle restrictions = rm.getApplicationRestrictions();
boolean allowCamera = restrictions.getBoolean("allow_camera", true);
String url = restrictions.getString("server_url", "https://ipipp.com/api");
// 注册变更监听
IntentFilter filter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle newRest = ((RestrictionsManager)
context.getSystemService(Context.RESTRICTIONS_SERVICE))
.getApplicationRestrictions();
// 根据newRest更新配置
}
};
registerReceiver(receiver, filter);
常见配置错误与排查思路
实际接入时,最容易出错的是key命名不规范。系统要求key必须全小写,若写成allowCamera,部分MDM会直接丢弃该条目。另一个问题是文件未正确打包,可以用aapt dump resources检查apk里是否包含res/xml/app_restrictions.xml。此外,restrictionType写错(例如把integer写成number)也会导致解析失败。
如果应用始终收不到配置,建议先在设备上通过adb shell pm get-app-restrictions查看系统侧实际下发的Bundle,再比对文件中的key。同时确认设备处于受管状态(如通过Test DPC应用模拟),非受管设备不会触发任何受管配置流程。
| 错误现象 | 可能原因 | 解决办法 |
|---|---|---|
| MDM界面不显示配置项 | restrictionType不支持或entry缺失 | 核对类型并使用标准写法 |
| 应用读到的value为null | key大小写不对或未下发 | 统一小写key,检查下发日志 |
| 更新配置无反应 | 未注册广播接收器 | 监听ACTION_APPLICATION_RESTRICTIONS_CHANGED |
结合企业场景的最佳实践
对于面向企业的App,建议把所有可能需IT管控的项都声明在app_restrictions.xml中,例如禁用截图、强制隧道地址、预设组织ID等。这样管理员零代码即可完成部署,降低现场实施成本。同时,将敏感配置(如token)设计为只读下发,不在应用内提供修改入口,可提升安全性。
在调试阶段,可以使用Google提供的Test DPC应用模拟企业环境,快速验证schema是否被正确认识。上线后,配合MDM厂商的模板功能,就能实现一键批量配置,避免每台设备手工操作。合理的app_restrictions.xml设计,是Android企业应用合规接入的关键一步。
app_restrictionsAndroid_for_Workrestrictions_schema修改时间:2026-08-09 13:03:32