summaryrefslogtreecommitdiffstats
path: root/docs/html/training/enterprise/app-restrictions.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training/enterprise/app-restrictions.jd')
-rw-r--r--docs/html/training/enterprise/app-restrictions.jd351
1 files changed, 351 insertions, 0 deletions
diff --git a/docs/html/training/enterprise/app-restrictions.jd b/docs/html/training/enterprise/app-restrictions.jd
new file mode 100644
index 0000000..fc5dfcc
--- /dev/null
+++ b/docs/html/training/enterprise/app-restrictions.jd
@@ -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>&lt;application&gt;</code></a> element:
+</p>
+
+<pre>&lt;meta-data android:name="android.content.APP_RESTRICTIONS"
+ android:resource="@xml/app_restrictions" /&gt;
+</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>&lt;restrictions&gt;</code> element, which contains
+ one <code>&lt;restriction&gt;</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>&lt;restriction&gt;</code> element like this:
+</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;restrictions xmlns:android="http://schemas.android.com/apk/res/android" &gt;
+
+ &lt;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" /&gt;
+
+&lt;/restrictions&gt;
+</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() {
+ &#64;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>