如果您要开发面向企业市场的应用,则可能需要 以满足组织政策规定的特定要求。 受管配置,以前称为“应用限制”, 允许单位的 IT 管理员远程指定 。此功能对于由组织批准的 部署到工作资料的应用
例如,组织可能会要求获得批准的应用 IT 管理员执行以下操作:
- 在网络浏览器中允许或屏蔽网址
- 配置是允许应用通过移动网络同步内容,还是仅允许 通过 Wi-Fi
- 配置应用的电子邮件设置
本指南介绍如何在 Google Cloud 控制台中实现受管配置设置。 。如需查看采用托管配置的示例应用,请参阅 ManagedConfigurations。 如果您是企业移动管理 (EMM) 开发者,请参阅 Android Management API 指南。
注意:由于历史原因,这些配置设置都称为
限制,通过使用此
字词(例如 RestrictionsManager
)。不过,这些
实际上可以实现各种配置选项
不仅仅是限制应用功能
远程配置概览
应用定义了可以远程访问的受管配置选项 由 IT 管理员设置这些设置是任意设置 由受管配置提供商更改。如果您的应用在工作资料中运行, IT 管理员可以更改应用的受管配置。
受管配置提供程序是在同一设备上运行的另一个应用。 此应用通常由 IT 管理员控制。通过 IT 管理员将配置更改传达给受管 配置提供程序应用。该应用进而更改应用的配置。
如需提供由外部管理的配置,请执行以下操作:
- 在应用清单中声明托管配置。操作 因此 IT 管理员可以读取应用的 配置。
- 每当应用恢复时,都使用
RestrictionsManager
对象检查当前的 托管配置,并将应用的界面和行为更改为 都符合这些配置 - 监听
ACTION_APPLICATION_RESTRICTIONS_CHANGED
intent。收到此信息后 请查看RestrictionsManager
了解 当前的托管配置是怎样的, 应用的行为。
定义托管配置
您的应用可以支持您要定义的任何托管配置。您将声明 托管配置文件中存放应用的托管配置,并声明 配置配置文件通过创建配置文件 检查您的应用提供的托管配置。EMM 合作伙伴 可以使用 Google Play API 读取应用的配置。
如需定义应用的远程配置选项,请将以下元素
(位于清单的
<ph type="x-smartling-placeholder"></ph>
<application>
元素:
<meta-data android:name="android.content.APP_RESTRICTIONS" android:resource="@xml/app_restrictions" />
在应用的app_restrictions.xml
res/xml
目录中。该文件的结构
对 RestrictionsManager
的引用。该文件包含
单个顶级 <restrictions>
元素,其中包含
每个配置对应一个 <restriction>
子元素
应用提供的选项
注意:请勿创建本地化版本的 受管配置文件。您的应用只能有一个 单个受管配置文件 所有语言区域。
在企业环境中,EMM 通常会使用 用于为 IT 生成远程控制台的配置架构 这样管理员就可以远程配置您的 应用。
受管配置提供程序可以查询应用以查找详细信息 应用的可用配置,包括配置说明 文本。配置提供商和 IT 管理员可以更改您的应用 受管配置。
例如,假设您的应用可以远程配置为允许或禁止
通过移动网络连接下载数据。您的应用可能会有
<restriction>
元素,如下所示:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android"> <restriction android:key="downloadOnCellular" android:title="@string/download_on_cell_title" android:restrictionType="bool" android:description="@string/download_on_cell_description" android:defaultValue="true" /> </restrictions>
您可以使用每个配置的 android:key
属性来
从受管配置包中读取其值。因此
每项配置都必须具有唯一的键字符串,且该字符串
无法本地化。必须使用字符串字面量指定。
注意:在正式版应用中,android:title
和
android:description
应从本地化资源绘制
文件,如
利用资源进行本地化。
应用在 bundle_array
中使用 bundle 来定义限制。
例如,具有多个 VPN 连接选项的应用可以定义每台 VPN 服务器
bundle
中的配置,其中包含多个
在 bundle 数组中归为一组的 app bundle:
<?xml version="1.0" encoding="utf-8"?> <restrictions xmlns:android="http://schemas.android.com/apk/res/android" > <restriction android:key="vpn_configuration_list" android:restrictionType="bundle_array"> <restriction android:key="vpn_configuration" android:restrictionType="bundle"> <restriction android:key="vpn_server" android:restrictionType="string"/> <restriction android:key="vpn_username" android:restrictionType="string"/> <restriction android:key="vpn_password" android:restrictionType="string"/> </restriction> </restriction> </restrictions>
android:restrictionType
元素支持的类型
表 1 中列出了这些列,
RestrictionsManager
和
RestrictionEntry
。
类型 | android:restrictionType | 典型用法 |
---|---|---|
TYPE_BOOLEAN
|
"bool" |
布尔值(true 或 false)。 |
TYPE_STRING
|
"string" |
字符串值,例如名称。 |
TYPE_INTEGER
|
"integer" |
一个整数,其值来自于
MIN_VALUE 至
MAX_VALUE 。
|
TYPE_CHOICE
|
"choice" |
从 android:entryValues 中选择的字符串值。
通常以单选列表的形式显示。
|
TYPE_MULTI_SELECT
|
"multi-select" |
一个包含从 android:entryValues 中选择的值的字符串数组。
此属性用于呈现一个多选列表,其中多个选项
条目。
|
TYPE_NULL
|
"hidden" |
隐藏的限制类型。对于 需要转给其他客户,但不应向其 和用户在界面中使用存储单个字符串值。 |
TYPE_BUNDLE_ARRAY
|
"bundle_array" |
用于存储限制数组
bundles 。适用于 Android 6.0(API 级别 23)。
|
注意:android:entryValues
属于机器可读类型,不能
已本地化。使用 android:entries
表示可以本地化的人类可读值。
每个条目在 android:entryValues
中都必须有相应的索引。
检查受管配置
当其他应用更改其首次登录设置时,您的应用不会自动收到通知。 配置设置。您需要检查 配置是指应用启动或恢复的时间,并监听 系统意图,以了解 应用正在运行。
为了确定当前的配置设置,您的应用会使用
RestrictionsManager
对象。您的应用应
可在以下时间检查当前的受管配置:
- 当应用启动或恢复时,在
onResume()
种方式 - 当应用收到配置更改通知时(如 监听受管配置 变更
如需获取 RestrictionsManager
对象,请获取当前的
getActivity()
的活动,之后
调用该 activity 的 Activity.getSystemService()
方法:
Kotlin
var myRestrictionsMgr = activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager
Java
RestrictionsManager myRestrictionsMgr = (RestrictionsManager) getActivity() .getSystemService(Context.RESTRICTIONS_SERVICE);
有了 RestrictionsManager
后,您就可以获取
通过调用其
getApplicationRestrictions()
方法:
Kotlin
var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions
Java
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
注意:为方便起见,您还可以提取当前的
具有 UserManager
的
UserManager.getApplicationRestrictions()
。此方法与
与 RestrictionsManager.getApplicationRestrictions()
相同。
getApplicationRestrictions()
方法需要从数据存储中读取数据,因此
请务必谨慎操作。不要在每次需要调用时都调用此方法,
以了解当前配置。而是应该在您的应用
启动或恢复,并缓存提取的受管配置包。然后收听
ACTION_APPLICATION_RESTRICTIONS_CHANGED
intent 以了解
在应用处于活动状态时进行更改,如
监听受管配置更改。
读取和应用托管配置
getApplicationRestrictions()
方法会返回 Bundle
包含已设置的每个配置的键值对。通过
值均为 Boolean
、int
、
String
和String[]
。安装
受管配置Bundle
,您可以查看当前的
使用标准 Bundle
方法对配置设置进行
这些数据类型,例如 getBoolean()
或
getString()
。
注意:受管配置 Bundle
对于由管理员明确设置的每项配置,
受管配置提供程序。不过,您不能假定
仅因为您定义了一个默认值,所以捆绑包中
的值。
您的应用应根据当前
受管配置设置。例如,如果您的应用有一个
指定是否允许通过
并且你发现该配置已设为
false
,则您必须停用数据下载功能,除非
设备具有 Wi-Fi 连接,如以下示例代码所示:
Kotlin
val appCanUseCellular: Boolean = if (appRestrictions.containsKey("downloadOnCellular")) { appRestrictions.getBoolean("downloadOnCellular") } else { // cellularDefault is a boolean using the restriction's default value cellularDefault } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
Java
boolean appCanUseCellular; if (appRestrictions.containsKey("downloadOnCellular")) { appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular"); } else { // cellularDefault is a boolean using the restriction's default value appCanUseCellular = cellularDefault; } if (!appCanUseCellular) { // ...turn off app's cellular-download functionality // ...show appropriate notices to user }
如需应用多个嵌套限制,请参阅
bundle_array
限制条目表示为 Parcelable
对象的集合
并转换为 Bundle
类型。在此示例中,每个 VPN 的配置
数据会解析并用于构建服务器连接选项列表:
Kotlin
// VpnConfig is a sample class used store config data, not defined val vpnConfigs = mutableListOf<VpnConfig>() val parcelables: Array<out Parcelable>? = appRestrictions.getParcelableArray("vpn_configuration_list") if (parcelables?.isNotEmpty() == true) { // iterate parcelables and cast as bundle parcelables.map { it as Bundle }.forEach { vpnConfigBundle -> // parse bundle data and store in VpnConfig array vpnConfigs.add(VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))) } } if (vpnConfigs.isNotEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
Java
// VpnConfig is a sample class used store config data, not defined List<VpnConfig> vpnConfigs = new ArrayList<>(); Parcelable[] parcelables = appRestrictions.getParcelableArray("vpn_configuration_list"); if (parcelables != null && parcelables.length > 0) { // iterate parcelables and cast as bundle for (int i = 0; i < parcelables.length; i++) { Bundle vpnConfigBundle = (Bundle) parcelables[i]; // parse bundle data and store in VpnConfig array vpnConfigs.add(new VpnConfig() .setServer(vpnConfigBundle.getString("vpn_server")) .setUsername(vpnConfigBundle.getString("vpn_username")) .setPassword(vpnConfigBundle.getString("vpn_password"))); } } if (!vpnConfigs.isEmpty()) { // ...choose a VPN configuration or prompt user to select from list }
监听受管配置更改
每当应用的托管配置发生更改时,系统都会触发
ACTION_APPLICATION_RESTRICTIONS_CHANGED
intent。您的应用必须监听
以便您可以在配置设置时更改应用的行为
更改。
注意:ACTION_APPLICATION_RESTRICTIONS_CHANGED
intent 只会发送给监听器
是动态注册的监听器,而非声明的监听器
。
以下代码展示了如何为 此 intent:
Kotlin
val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED) val restrictionsReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { // Get the current configuration bundle val appRestrictions = myRestrictionsMgr.applicationRestrictions // Check current configuration settings, change your app's UI and // functionality as necessary. } } registerReceiver(restrictionsReceiver, restrictionsFilter)
Java
IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // Get the current configuration bundle Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions(); // Check current configuration settings, change your app's UI and // functionality as necessary. } }; registerReceiver(restrictionsReceiver, restrictionsFilter);
注意:通常情况下,您的应用不需要收到通知 暂停期间的配置更改。您应该取消注册 您的广播接收器。当应用恢复时, 首先检查当前的受管配置(如 检查托管配置),然后注册 您的广播接收器,以确保您收到配置更改的通知 发生的事件
向 EMM 发送受管配置反馈
将受管配置更改应用到您的应用后,最佳做法是向 EMM 告知以下事项: 更改的状态Android 支持一项称为关键应用状态的功能, 用于在每次您的应用尝试应用受管配置更改时发送反馈。这个 反馈可以用来确认您的应用已成功设置受管配置, 如果您的应用无法应用指定的更改,请添加错误消息。
EMM 提供商能够检索此反馈,并将其显示在其控制台中,方便 IT 部门使用 管理员查看权限。有关详情,请参阅向 EMM 发送应用反馈 提供关于该主题的信息,包括有关如何为应用添加反馈支持的详细指南。
更多代码示例
ManagedConfigurations 示例进一步演示了如何使用本页介绍的 API。