From 79cb98c6ced6aaf1ea102e4b927cfb0b99bbf67b Mon Sep 17 00:00:00 2001 From: Andrew Solovay Date: Wed, 11 Feb 2015 13:12:18 -0800 Subject: docs: New "implementing app restrictions" doc New doc on app restrictions, aimed primarily at developers of enterprise apps. See first comment for doc stage location. Change-Id: I561780d218c78ae0dc4e4e54d925302c718f96ac --- docs/html/training/enterprise/app-restrictions.jd | 351 ++++++++++++++++++++++ docs/html/training/training_toc.cs | 32 +- 2 files changed, 378 insertions(+), 5 deletions(-) create mode 100644 docs/html/training/enterprise/app-restrictions.jd 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 + +
+
+ +

This lesson teaches you to

+
    +
  1. Define App Restrictions
  2. +
  3. Check App Restrictions
  4. +
  5. Listen for App Restriction Changes
  6. +
+ + +

Resources

+ + +
+
+ +

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.

+ +

For example, an enterprise might require that approved apps allow the +enterprise administrator to:

+ + + +

+ This guide shows how to implement these configuration settings in your app. +

+ +

+ Note: For historical reasons, these configuration settings are known as + restrictions, 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. +

+ +

+ Remote Configuration Overview +

+ +

+ 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. +

+ +

+ 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. +

+ +

+ To provide externally configurable restrictions: +

+ + + +

+ Define App Restrictions +

+ +

+ Your app can support any restrictions you want to define. You declare the + app's restrictions in a restrictions file, 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. +

+ +

+ To define your app's remote configuration options, put the following element + in your manifest's + + <application> element: +

+ +
<meta-data android:name="android.content.APP_RESTRICTIONS"
+    android:resource="@xml/app_restrictions" />
+
+ +

+ Create a file named app_restrictions.xml in your app's + res/xml directory. The structure of that file is described in + the reference for {@link android.content.RestrictionsManager}. The file has a + single top-level <restrictions> element, which contains + one <restriction> child element for every configuration + option the app has. +

+ +

+ Note: 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. +

+ +

+ 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. +

+ +

+ 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 + <restriction> element like this: +

+ +
+<?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>
+
+ +

+ The supported types for the android:restrictionType element are + documented in the reference for {@link android.content.RestrictionsManager}. +

+ +

+ You use each restriction's android:key attribute to read its + value from a restrictions bundle. For this reason, each restriction must have + a unique key string, and the string cannot be localized. It must be + specified with a string literal. +

+ +

+ Note: In a production app, android:title and + android:description should be drawn from a localized resource + file, as described in Localizing with + Resources. +

+ +

+ 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. +

+ +

+ Check App Restrictions +

+ +

+ 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. +

+ +

+ 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: +

+ + + +

+ 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: +

+ +
RestrictionsManager myRestrictionsMgr =
+    (RestrictionsManager) getActivity()
+        .getSystemService(Context.RESTRICTIONS_SERVICE);
+ +

+ 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: +

+ +
Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
+ +

+ Note: 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()}. +

+ +

+ 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 Listen for + Device Configuration Changes. +

+ +

+ Reading and applying restrictions +

+ +

+ 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 Boolean, int, + String, and String[]. 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()}. +

+ +

+ Note: The restrictions {@link android.os.Bundle} contains + one item for every restriction that has been explicitly set by a restrictions + provider. However, you cannot assume that a restriction will be + present in the bundle just because you defined a default value in the + restrictions XML file. +

+ +

+ 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 false, you would have to disable data + download except when the device has a Wi-Fi connection, as shown in the + following example code: +

+ +
+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
+}
+ +

+ Listen for App Restriction Changes +

+ +

+ 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: +

+ +
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 appRestrictions =
+
+    myRestrictionsMgr.getApplicationRestrictions();
+
+    // Check current restrictions settings, change your app's UI and
+    // functionality as necessary.
+
+  }
+
+};
+
+registerReceiver(restrictionsReceiver, restrictionsFilter);
+
+

+ Note: 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 Check Device Restrictions), then register your + broadcast receiver to make sure you're notified about restriction changes + that happen while the app is active. +

diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index c59d8ff..89e72f1 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -1040,6 +1040,32 @@ include the action bar on devices running Android 2.1 or higher." + + + + + -
  • - Ensuring Compatibility with Managed Profiles - -
  • @@ -1887,4 +1909,4 @@ results." buildToggleLists(); changeNavLang(getLangPref()); //--> - \ No newline at end of file + -- cgit v1.1