diff options
Diffstat (limited to 'docs/html/training/enterprise/app-restrictions.jd')
-rw-r--r-- | docs/html/training/enterprise/app-restrictions.jd | 351 |
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><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> |