diff --git a/docs/html/training/enterprise/app-restrictions.jd b/docs/html/training/enterprise/app-restrictions.jd new file mode 100644 index 0000000000000..fc5dfcc9d0fdc --- /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 + +
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. +
+ ++ 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: +
+ ++ 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. +
+ ++ 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. +
+ +
+ 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
+}
+
++ 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 c59d8ff9ffc9e..89e72f1706b91 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." + +