* commit '6ffe1058463e5f4e65aa131796b37c0443d1b44b': docs: New "implementing app restrictions" doc
This commit is contained in:
351
docs/html/training/enterprise/app-restrictions.jd
Normal file
351
docs/html/training/enterprise/app-restrictions.jd
Normal file
@@ -0,0 +1,351 @@
|
||||
page.title=Implementing App Restrictions
|
||||
page.metaDescription=Learn how to implement app restrictions and configuration settings that can be changed by other apps on the same device.
|
||||
@jd:body
|
||||
|
||||
<div id="tb-wrapper">
|
||||
<div id="tb">
|
||||
|
||||
<h2>This lesson teaches you to</h2>
|
||||
<ol>
|
||||
<li><a href="#define_restrictions">Define App Restrictions</a></li>
|
||||
<li><a href="#check_restrictions">Check App Restrictions</a></li>
|
||||
<li><a href="#listen">Listen for App Restriction Changes</a></li>
|
||||
</ol>
|
||||
|
||||
<!-- related docs (NOT javadocs) -->
|
||||
<h2>Resources</h2>
|
||||
<ul>
|
||||
<li><a href="{@docRoot}samples/AppRestrictionSchema/index.html">AppRestrictionSchema</a>
|
||||
sample app</li>
|
||||
<li><a href="{@docRoot}samples/AppRestrictionEnforcer/index.html">AppRestrictionEnforcer</a>
|
||||
sample app</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>If you are developing apps for the enterprise market, you may need to satisfy
|
||||
particular requirements set by a company's policies. Application restrictions
|
||||
allow the enterprise administrator to remotely specify settings for apps.
|
||||
This capability is particularly useful for enterprise-approved apps deployed to
|
||||
a managed profile.</p>
|
||||
|
||||
<p>For example, an enterprise might require that approved apps allow the
|
||||
enterprise administrator to:</p>
|
||||
|
||||
<ul>
|
||||
<li>Whitelist or blacklist URLs for a web browser</li>
|
||||
<li>Configure whether an app is allowed to sync content via cellular, or just
|
||||
by Wi-Fi</li>
|
||||
<li>Configure the app's email settings</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This guide shows how to implement these configuration settings in your app.
|
||||
</p>
|
||||
|
||||
<p class="note">
|
||||
<strong>Note:</strong> For historical reasons, these configuration settings are known as
|
||||
<em>restrictions,</em> and are implemented with files and classes that use this
|
||||
term (such as {@link android.content.RestrictionsManager}). However, these
|
||||
restrictions can actually implement a wide range of configuration options,
|
||||
not just restrictions on app functionality.
|
||||
</p>
|
||||
|
||||
<h2 id="overview">
|
||||
Remote Configuration Overview
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Apps define the restrictions and configuration options that can be remotely
|
||||
set by an administrator. These restrictions are
|
||||
arbitrary configuration settings that can be changed by a restrictions
|
||||
provider. If your app is running on an enterprise device's managed
|
||||
profile, the enterprise administrator can change your app's restrictions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The restrictions provider is another app running on the same device.
|
||||
This app is typically controlled by the enterprise administrator. The
|
||||
enterprise administrator communicates restriction changes to the restrictions
|
||||
provider app. That app, in turn, changes the restrictions on your app.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To provide externally configurable restrictions:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Declare the restrictions in your app manifest. Doing so allows the
|
||||
enterprise administrator to read the app's restrictions through Google
|
||||
Play APIs.
|
||||
</li>
|
||||
|
||||
<li>Whenever the app resumes, use the {@link
|
||||
android.content.RestrictionsManager} object to check the current
|
||||
restrictions, and change your app's UI and behavior to conform with those
|
||||
restrictions.
|
||||
</li>
|
||||
|
||||
<li>Listen for the
|
||||
{@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
|
||||
ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this
|
||||
broadcast, check the {@link android.content.RestrictionsManager} to see what
|
||||
the current restrictions are, and make any necessary changes to your app's
|
||||
behavior.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="define_restrictions">
|
||||
Define App Restrictions
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Your app can support any restrictions you want to define. You declare the
|
||||
app's restrictions in a <em>restrictions file</em>, and declare the
|
||||
restrictions file in the manifest. Creating a restrictions file allows other
|
||||
apps to examine the restrictions your app provides. Enterprise Mobility
|
||||
Management (EMM) partners can read your app's restrictions by using Google
|
||||
Play APIs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To define your app's remote configuration options, put the following element
|
||||
in your manifest's
|
||||
<a href="{@docRoot}guide/topics/manifest/application-element.html">
|
||||
<code><application></code></a> element:
|
||||
</p>
|
||||
|
||||
<pre><meta-data android:name="android.content.APP_RESTRICTIONS"
|
||||
android:resource="@xml/app_restrictions" />
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Create a file named <code>app_restrictions.xml</code> in your app's
|
||||
<code>res/xml</code> directory. The structure of that file is described in
|
||||
the reference for {@link android.content.RestrictionsManager}. The file has a
|
||||
single top-level <code><restrictions></code> element, which contains
|
||||
one <code><restriction></code> child element for every configuration
|
||||
option the app has.
|
||||
</p>
|
||||
|
||||
<p class="note">
|
||||
<strong>Note:</strong> Do not create localized versions of the restrictions
|
||||
file. Your app is only allowed to have a single restrictions file,
|
||||
so restrictions will be consistent for your app in all locales.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In an enterprise environment, an EMM will typically use the restrictions
|
||||
schema to generate a remote console for IT administrators, so the
|
||||
administrators can remotely configure your application.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, suppose your app can be remotely configured to allow or forbid
|
||||
it to download data over a cellular connection. Your app could have a
|
||||
<code><restriction></code> element like this:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<restriction
|
||||
android:key="downloadOnCellular"
|
||||
android:title="App is allowed to download data via cellular"
|
||||
android:restrictionType="bool"
|
||||
android:description="If 'false', app can only download data via Wi-Fi"
|
||||
android:defaultValue="true" />
|
||||
|
||||
</restrictions>
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
The supported types for the <code>android:restrictionType</code> element are
|
||||
documented in the reference for {@link android.content.RestrictionsManager}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You use each restriction's <code>android:key</code> attribute to read its
|
||||
value from a restrictions bundle. For this reason, each restriction must have
|
||||
a unique key string, and the string <em>cannot</em> be localized. It must be
|
||||
specified with a string literal.
|
||||
</p>
|
||||
|
||||
<p class="note">
|
||||
<strong>Note:</strong> In a production app, <code>android:title</code> and
|
||||
<code>android:description</code> should be drawn from a localized resource
|
||||
file, as described in <a href=
|
||||
"{@docRoot}guide/topics/resources/localization.html">Localizing with
|
||||
Resources</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The restrictions provider can query the app to find details on the app's
|
||||
available restrictions, including their description text. Restrictions
|
||||
providers and enterprise administrators can change your app's restrictions at
|
||||
any time, even when the app is not running.
|
||||
</p>
|
||||
|
||||
<h2 id="check_restrictions">
|
||||
Check App Restrictions
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Your app is not automatically notified when other apps change its restriction
|
||||
settings. Instead, you need to check what the restrictions are when your app
|
||||
starts or resumes, and listen for a system intent to find out if the
|
||||
restrictions change while your app is running.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To find out the current restriction settings, your app uses a {@link
|
||||
android.content.RestrictionsManager} object. Your app should check for the
|
||||
current restrictions at the following times:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>When the app starts or resumes, in its
|
||||
{@link android.app.Activity#onResume onResume()} method
|
||||
</li>
|
||||
|
||||
<li>When the app is notified of a restriction change, as described in
|
||||
<a href="#listen">Listen for Device Configuration
|
||||
Changes</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
To get a {@link android.content.RestrictionsManager} object, get the current
|
||||
activity with {@link android.app.Fragment#getActivity getActivity()}, then
|
||||
call that activity's {@link android.app.Activity#getSystemService
|
||||
Activity.getSystemService()} method:
|
||||
</p>
|
||||
|
||||
<pre>RestrictionsManager myRestrictionsMgr =
|
||||
(RestrictionsManager) getActivity()
|
||||
.getSystemService(Context.RESTRICTIONS_SERVICE);</pre>
|
||||
|
||||
<p>
|
||||
Once you have a {@link android.content.RestrictionsManager}, you can get the current restrictions
|
||||
settings by calling its
|
||||
{@link android.content.RestrictionsManager#getApplicationRestrictions
|
||||
getApplicationRestrictions()} method:
|
||||
</p>
|
||||
|
||||
<pre>Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();</pre>
|
||||
|
||||
<p class="note">
|
||||
<strong>Note:</strong> For convenience, you can also fetch the current
|
||||
restrictions with a {@link android.os.UserManager}, by calling {@link
|
||||
android.os.UserManager#getApplicationRestrictions
|
||||
UserManager.getApplicationRestrictions()}. This method behaves exactly the
|
||||
same as {@link android.content.RestrictionsManager#getApplicationRestrictions
|
||||
RestrictionsManager.getApplicationRestrictions()}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The {@link android.content.RestrictionsManager#getApplicationRestrictions
|
||||
getApplicationRestrictions()} method requires reading from data storage, so
|
||||
it should be done sparingly. Do not call this method every time you need to
|
||||
know the current restrictions. Instead, you should call it once when your app
|
||||
starts or resumes, and cache the fetched restrictions bundle. Then listen for
|
||||
the {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
|
||||
ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent to find out if restrictions
|
||||
change while your app is active, as described in <a href="#listen">Listen for
|
||||
Device Configuration Changes</a>.
|
||||
</p>
|
||||
|
||||
<h3 id="read_restrictions">
|
||||
Reading and applying restrictions
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
The {@link android.content.RestrictionsManager#getApplicationRestrictions
|
||||
getApplicationRestrictions()} method returns a {@link android.os.Bundle}
|
||||
containing a key-value pair for each restriction that has been set. The
|
||||
values are all of type <code>Boolean</code>, <code>int</code>,
|
||||
<code>String</code>, and <code>String[]</code>. Once you have the
|
||||
restrictions {@link android.os.Bundle}, you can check the current
|
||||
restrictions settings with the standard {@link android.os.Bundle} methods for
|
||||
those data types, such as {@link android.os.Bundle#getBoolean getBoolean()}
|
||||
or
|
||||
{@link android.os.Bundle#getString getString()}.
|
||||
</p>
|
||||
|
||||
<p class="note">
|
||||
<strong>Note:</strong> The restrictions {@link android.os.Bundle} contains
|
||||
one item for every restriction that has been explicitly set by a restrictions
|
||||
provider. However, you <em>cannot</em> assume that a restriction will be
|
||||
present in the bundle just because you defined a default value in the
|
||||
restrictions XML file.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is up to your app to take appropriate action based on the current
|
||||
restrictions settings. For example, if your app has a restriction specifying
|
||||
whether it can download data over a cellular connection, and you find that
|
||||
the restriction is set to <code>false</code>, you would have to disable data
|
||||
download except when the device has a Wi-Fi connection, as shown in the
|
||||
following example code:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
boolean appCanUseCellular;
|
||||
|
||||
if appRestrictions.containsKey("downloadOnCellular") {
|
||||
appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular");
|
||||
} else {
|
||||
// here, cellularDefault is a boolean set with the restriction's
|
||||
// default value
|
||||
appCanUseCellular = cellularDefault;
|
||||
}
|
||||
|
||||
if (!appCanUseCellular) {
|
||||
// ...turn off app's cellular-download functionality
|
||||
// ...show appropriate notices to user
|
||||
}</pre>
|
||||
|
||||
<h2 id="listen">
|
||||
Listen for App Restriction Changes
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Whenever an app's restrictions are changed, the system fires the
|
||||
{@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
|
||||
ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. Your app has to listen for
|
||||
this intent so you can change the app's behavior when the restriction settings
|
||||
change. The following code shows how to dynamically register a broadcast
|
||||
receiver for this intent:
|
||||
</p>
|
||||
|
||||
<pre>IntentFilter restrictionsFilter =
|
||||
new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
|
||||
|
||||
BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
|
||||
@Override public void onReceive(Context context, Intent intent) {
|
||||
|
||||
// Get the current restrictions bundle
|
||||
Bundle <code>appRestrictions</code> =
|
||||
|
||||
myRestrictionsMgr.getApplicationRestrictions();
|
||||
|
||||
// Check current restrictions settings, change your app's UI and
|
||||
// functionality as necessary.
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
registerReceiver(restrictionsReceiver, restrictionsFilter);
|
||||
</pre>
|
||||
<p class="note">
|
||||
<strong>Note:</strong> Ordinarily, your app does not need to be notified
|
||||
about restriction changes when it is paused. Instead, you should unregister
|
||||
your broadcast receiver when the app is paused. When the app resumes, you
|
||||
first check for the current restrictions (as discussed in <a href=
|
||||
"#check_restrictions">Check Device Restrictions</a>), then register your
|
||||
broadcast receiver to make sure you're notified about restriction changes
|
||||
that happen while the app is active.
|
||||
</p>
|
||||
@@ -1040,6 +1040,32 @@ include the action bar on devices running Android 2.1 or higher."
|
||||
<!-- End: Building for Auto -->
|
||||
|
||||
|
||||
<!-- Start: Building for Work -->
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/enterprise/index.html">
|
||||
<span class="small">Building Apps for</span><br/>
|
||||
Work
|
||||
</a>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="<?cs var:toroot ?>training/enterprise/app-compatibility.html">
|
||||
Ensuring Compatibility with Managed Profiles
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/enterprise/app-restrictions.html">
|
||||
Implementing App Restrictions
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/enterprise/work-policy-ctrl.html">
|
||||
Building a Work Policy Controller
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- End: Building for Work -->
|
||||
|
||||
|
||||
<li class="nav-section">
|
||||
<div class="nav-section-header">
|
||||
<a href="<?cs var:toroot ?>training/best-ux.html">
|
||||
@@ -1752,10 +1778,6 @@ results."
|
||||
Enhancing Security with Device Management Policies
|
||||
</a>
|
||||
</li>
|
||||
<li><a href="<?cs var:toroot ?>training/enterprise/app-compatibility.html">
|
||||
Ensuring Compatibility with Managed Profiles
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1887,4 +1909,4 @@ results."
|
||||
buildToggleLists();
|
||||
changeNavLang(getLangPref());
|
||||
//-->
|
||||
</script>
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user