Implementing App Restrictions,Building a Device Policy Controller

desaco發表於2016-01-23

>Implementing App Restrictions

 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. 

 To provide externally configurable restrictions:

  • Declare the restrictions in your app manifest. Doing so allows the enterprise administrator to read the app's restrictions through Google Play APIs.
  • Whenever the app resumes, use the RestrictionsManager object to check the current restrictions, and change your app's UI and behavior to conform with those restrictions.
  • Listen for the ACTION_APPLICATION_RESTRICTIONS_CHANGED intent. When you receive this broadcast, check the RestrictionsManager to see what the current restrictions are, and make any necessary changes to your app's behavior.

 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>

  >To find out the current restriction settings, your app uses a RestrictionsManager object. Your app should check for the current restrictions at the following times:

To get a RestrictionsManager object, get the current activity with getActivity(), then call that activity'sActivity.getSystemService() method:

RestrictionsManager myRestrictionsMgr =
    (RestrictionsManager) getActivity()
        .getSystemService(Context.RESTRICTIONS_SERVICE);
Note: For convenience, you can also fetch the current restrictions with a UserManager, by callingUserManager.getApplicationRestrictions(). This method behaves exactly the same asRestrictionsManager.getApplicationRestrictions().

    Whenever an app's restrictions are changed, the system fires the 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.

 Note: The ACTION_APPLICATION_RESTRICTIONS_CHANGED intent is sent only to listeners that are dynamically registered, not to listeners that are declared in the app manifest.

 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.

>Building a Device Policy Controller

 In an Android for Work deployment, an enterprise needs to maintain control over certain aspects of the employees' devices. The enterprise needs to ensure that work-related information is encrypted and is kept separate from employees' personal data. The enterprise may also need to limit device capabilities, such as whether the device is allowed to use its camera. And the enterprise may require that approved apps provide app restrictions, so the enterprise can turn app capability on or off as needed.

 Note: A device policy controller is built on the existing model used for device administration applications, as described in Device Administration. In particular, your app needs to create a subclass ofDeviceAdminReceiver, as described in that document.

 If the user can use their own device, the enterprise has to worry that confidential information (like employee emails and contacts) are on a device the enterprise does not control.

 To address this situation, Android 5.0 (API level 21) allows enterprises to set up a special work user profile using the Managed Profile API. This user profile is called a managed profile, or a work profile in the Android for Work program. If a device has a managed profile for work, the profile's settings are under the control of the enterprise administrator. The administrator can choose which apps are allowed for that profile, and can control just what device features are available to the profile.

 > To create a managed profile on a device that already has a personal profile, first check that the device can support a managed profile, by seeing if the device supports the FEATURE_MANAGED_USERS system feature:

PackageManager pm = getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {

    // This device does not support native managed profiles!

}

If the device supports managed profiles, create one by sending an intent with anACTION_PROVISION_MANAGED_PROFILE action. Include the device admin package name as an extra.

Activity provisioningActivity = getActivity();

// You'll need the package name for the WPC app.
String myWPCPackageName = "com.example.myWPCApp";

// Set up the provisioning intent
Intent provisioningIntent =
        new Intent("android.app.action.PROVISION_MANAGED_PROFILE");
intent.putExtra(myWPCPackageName,
        provisioningActivity.getApplicationContext().getPackageName());

if (provisioningIntent.resolveActivity(provisioningActivity.getPackageManager())
         == null) {

    // No handler for intent! Can't provision this device.
    // Show an error message and cancel.
} else {

    // REQUEST_PROVISION_MANAGED_PROFILE is defined
    // to be a suitable request code
    startActivityForResult(provisioningIntent,
            REQUEST_PROVISION_MANAGED_PROFILE);
    provisioningActivity.finish();
}

Once you have completed these tasks, call the device policy manager's setProfileEnabled() method to activate the managed profile:

// Get the device policy manager
DevicePolicyManager myDevicePolicyMgr =
        (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);

ComponentName componentName = myDeviceAdminReceiver.getComponentName(this);

// Set the name for the newly created managed profile.
myDevicePolicyMgr.setProfileName(componentName, "My New Managed Profile");

// ...and enable the profile
manager.setProfileEnabled(componentName);
// Fetch the DevicePolicyManager
DevicePolicyManager myDevicePolicyMgr =
        (DevicePolicyManager) thisActivity
                .getSystemService(Context.DEVICE_POLICY_SERVICE);

// Set up the restrictions bundle
bundle restrictionsBundle = new Bundle();
restrictionsBundle.putBoolean("downloadByCellular", false);

// Pass the restrictions to the policy manager. Assume the WPC app
// already has a DeviceAdminReceiver defined (myDeviceAdminReceiver).
myDevicePolicyMgr.setApplicationRestrictions(
        myDeviceAdminReceiver, "com.example.newsfetcher", restrictionsBundle);

Note: The device policy service conveys the restrictions change to the app you name. However, it is up to that app to actually implement the restriction. For example, in this case, the app would be responsible for disabling its ability to use cellular networks for video downloads. Setting the restriction does not cause the system to enforce this restriction on the app. For more information, see Implementing App Restrictions.

相關文章