diff --git a/docs/html/guide/topics/admin/device-admin.jd b/docs/html/guide/topics/admin/device-admin.jd index 7bbf5e65948d1..820c3c0e6c537 100644 --- a/docs/html/guide/topics/admin/device-admin.jd +++ b/docs/html/guide/topics/admin/device-admin.jd @@ -27,6 +27,12 @@ page.title=Device Administration
  • {@link android.app.admin.DevicePolicyManager}
  • {@link android.app.admin.DeviceAdminInfo}
  • +

    Related samples

    +
      +
    1. +DeviceAdminSample
    2. +
    @@ -201,6 +207,16 @@ access data. The value can be between 1 and 60 minutes. Specifies that the storage area should be encrypted, if the device supports it. Introduced in Android 3.0. + + Disable camera + + Specifies that the camera should be disabled. Note that this doesn't have +to be a permanent disabling. The camera can be enabled/disabled dynamically +based on context, time, and so on. Introduced in Android 4.0. + + + +

    Other features

    @@ -247,6 +263,7 @@ one of the last n passwords they previously used. locks.
  • Make the device lock immediately.
  • Wipe the device's data (that is, restore factory settings).
  • +
  • Disable the camera.
  • @@ -280,46 +297,38 @@ intent, expressed in the manifest as an intent filter.
  • A declaration of security policies used in metadata.
  • Here is an excerpt from the Device Administration sample manifest:

    -
    <activity android:name=".app.DeviceAdminSample$Controller"
    -          android:label="@string/activity_sample_device_admin">
    -    <intent-filter>
    -        <action android:name="android.intent.action.MAIN" />
    -        <category android:name="android.intent.category.SAMPLE_CODE" />
    -    </intent-filter>
    +
    <activity android:name=".app.DeviceAdminSample"
    +            android:label="@string/activity_sample_device_admin">
    +    <intent-filter>
    +        <action android:name="android.intent.action.MAIN" />
    +        <category android:name="android.intent.category.SAMPLE_CODE" />
    +    </intent-filter>
     </activity>
    -
    -<receiver android:name=".app.DeviceAdminSample"
    -          android:label="@string/sample_device_admin"
    -          android:description="@string/sample_device_admin_description"
    -          android:permission="android.permission.BIND_DEVICE_ADMIN">
    -    <meta-data android:name="android.app.device_admin"
    -               android:resource="@xml/device_admin_sample" />
    -    <intent-filter>
    -        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    -    </intent-filter>
    +<receiver android:name=".app.DeviceAdminSample$DeviceAdminSampleReceiver"
    +        android:label="@string/sample_device_admin"
    +        android:description="@string/sample_device_admin_description"
    +        android:permission="android.permission.BIND_DEVICE_ADMIN">
    +    <meta-data android:name="android.app.device_admin"
    +            android:resource="@xml/device_admin_sample" />
    +    <intent-filter>
    +        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    +    </intent-filter>
     </receiver>

    Note that:

    @@ -401,33 +413,34 @@ simply displays a {@link android.widget.Toast} notification in response to parti events. For example:

    public class DeviceAdminSample extends DeviceAdminReceiver {
     
    -...
    +    void showToast(Context context, String msg) {
    +        String status = context.getString(R.string.admin_receiver_status, msg);
    +        Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
    +    }
    +
         @Override
    -    public void onEnabled(Context context, Intent intent) {
    -        showToast(context, "Sample Device Admin: enabled");
    -    }
    +    public void onEnabled(Context context, Intent intent) {
    +        showToast(context, context.getString(R.string.admin_receiver_status_enabled));
    +    }
     
    -    @Override
    -    public CharSequence onDisableRequested(Context context, Intent intent) {
    -        return "This is an optional message to warn the user about disabling.";
    -    }
    +    @Override
    +    public CharSequence onDisableRequested(Context context, Intent intent) {
    +        return context.getString(R.string.admin_receiver_status_disable_warning);
    +    }
     
    -    @Override
    -    public void onDisabled(Context context, Intent intent) {
    -        showToast(context, "Sample Device Admin: disabled");
    -    }
    +    @Override
    +    public void onDisabled(Context context, Intent intent) {
    +        showToast(context, context.getString(R.string.admin_receiver_status_disabled));
    +    }
     
    -    @Override
    -    public void onPasswordChanged(Context context, Intent intent) {
    -        showToast(context, "Sample Device Admin: pw changed");
    -    }
    -
    -    void showToast(Context context, CharSequence msg) {
    -        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    +    @Override
    +    public void onPasswordChanged(Context context, Intent intent) {
    +        showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
         }
     ...
     }
    +

    Enabling the application

    One of the major events a device admin application has to handle is the user enabling the application. The user must explicitly enable the application for @@ -438,43 +451,50 @@ get any of the application's benefits.

    action that triggers the {@link android.app.admin.DevicePolicyManager#ACTION_ADD_DEVICE_ADMIN} intent. In the sample application, this happens when the user clicks the Enable -Admin button.

    -

    When the user clicks the Enable Admin button, the display -changes to prompt the user to enable the device admin application, as shown in figure +Admin checkbox.

    +

    When the user clicks the Enable Admin checkbox, the display +changes to prompt the user to activate the device admin application, as shown in figure 2.

    Figure 2. Sample Application: Activating the Application

    -

    Below is the code that gets executed when the user clicks the Enable -Admin button shown in figure 1.

    -
     private OnClickListener mEnableListener = new OnClickListener() {
    -    public void onClick(View v) {
    -        // Launch the activity to have the user enable our admin.
    -        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    -        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
    -               mDeviceAdminSample);
    -        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
    -               "Additional text explaining why this needs to be added.");
    -        startActivityForResult(intent, RESULT_ENABLE);
    -    }
    -};
    +

    Below is the code that gets executed when the user clicks the Enable Admin checkbox. This has the effect of triggering the +{@link android.preference.Preference.OnPreferenceChangeListener#onPreferenceChange(android.preference.Preference, java.lang.Object) onPreferenceChange()} +callback. This callback is invoked when the value of this {@link android.preference.Preference} has been changed by the user and is about to be set and/or persisted. If the user is enabling the application, the display +changes to prompt the user to activate the device admin application, as shown in figure +2. Otherwise, the device admin application is disabled.

    + +
    @Override
    +        public boolean onPreferenceChange(Preference preference, Object newValue) {
    +            if (super.onPreferenceChange(preference, newValue)) {
    +                return true;
    +            }
    +            boolean value = (Boolean) newValue;
    +            if (preference == mEnableCheckbox) {
    +                if (value != mAdminActive) {
    +                    if (value) {
    +                        // Launch the activity to have the user enable our admin.
    +                        Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
    +                        intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample);
    +                        intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
    +                                mActivity.getString(R.string.add_admin_extra_app_text));
    +                        startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
    +                        // return false - don't update checkbox until we're really active
    +                        return false;
    +                    } else {
    +                        mDPM.removeActiveAdmin(mDeviceAdminSample);
    +                        enableDeviceCapabilitiesArea(false);
    +                        mAdminActive = false;
    +                    }
    +                }
    +            } else if (preference == mDisableCameraCheckbox) {
    +                mDPM.setCameraDisabled(mDeviceAdminSample, value);
    +                ...
    +            }
    +            return true;
    +        }
    -... -// This code checks whether the device admin app was successfully enabled. -@Override -protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case RESULT_ENABLE: - if (resultCode == Activity.RESULT_OK) { - Log.i("DeviceAdminSample", "Administration enabled!"); -            } else { -                Log.i("DeviceAdminSample", "Administration enable FAILED!"); -            } -            return; -    } -    super.onActivityResult(requestCode, resultCode, data); -}

    The line intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, @@ -489,18 +509,17 @@ active. To do this it uses the {@link android.app.admin.DevicePolicyManager} met {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()}. Notice that the {@link android.app.admin.DevicePolicyManager} method {@link android.app.admin.DevicePolicyManager#isAdminActive(android.content.ComponentName) isAdminActive()} takes a {@link android.app.admin.DeviceAdminReceiver} component as its argument:

    +
     DevicePolicyManager mDPM;
     ...
    -boolean active = mDPM.isAdminActive(mDeviceAdminSample);
    -if (active) {
    -    // Admin app is active, so do some admin stuff
    -               ...
    -} else {
    -    // do something else
    +private boolean isActiveAdmin() {
    +    return mDPM.isAdminActive(mDeviceAdminSample);
     }
     
    + +

    Managing policies

    {@link android.app.admin.DevicePolicyManager} is a public class for managing policies enforced on a device. {@link android.app.admin.DevicePolicyManager} manages policies for one @@ -618,49 +637,6 @@ long pwExpiration; ... mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration); - -

    From the Device Administration API sample, here is the code -that updates the password expiration status:

    - -
    -DevicePolicyManager mDPM;
    -ComponentName mDeviceAdminSample;
    -private TextView mPasswordExpirationStatus;
    -...
    -void updatePasswordExpirationStatus() {
    -    boolean active = mDPM.isAdminActive(mDeviceAdminSample);
    -    String statusText;
    -    if (active) {
    -        long now = System.currentTimeMillis();
    -        // Query the DevicePolicyManager twice - first for the expiration values
    -        // set by the sample app, and later, for the system values (which may be different
    -        // if there is another administrator active.)
    -        long expirationDate = mDPM.getPasswordExpiration(mDeviceAdminSample);
    -        long mSecUntilExpiration = expirationDate - now;
    -        if (mSecUntilExpiration >= 0) {
    -            statusText = "Expiration in " + countdownString(mSecUntilExpiration);
    -        } else {
    -            statusText = "Expired " + countdownString(-mSecUntilExpiration) + " ago";
    -        }
    -
    -        // expirationTimeout is the cycle time between required password refresh
    -        long expirationTimeout = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
    -        statusText += " / timeout period " + countdownString(expirationTimeout);
    -
    -        // Now report the aggregate (global) expiration time
    -        statusText += " / Aggregate ";
    -        expirationDate = mDPM.getPasswordExpiration(null);
    -        mSecUntilExpiration = expirationDate - now;
    -        if (mSecUntilExpiration >= 0) {
    -            statusText += "expiration in " + countdownString(mSecUntilExpiration);
    -        } else {
    -            statusText += "expired " + countdownString(-mSecUntilExpiration) + " ago";
    -        }
    -    } else {
    -        statusText = "<inactive>";
    -    }
    -    mPasswordExpirationStatus.setText(statusText);
    Restrict password based on history
    @@ -718,6 +694,19 @@ mDPM.wipeData(0);

    The {@link android.app.admin.DevicePolicyManager#wipeData wipeData()} method takes as its parameter a bit mask of additional options. Currently the value must be 0.

    +

    Disable camera

    +

    Beginning with Android 4.0, you can disable the camera. Note that this doesn't have to be a permanent disabling. The camera can be enabled/disabled dynamically based on context, time, and so on.

    +

    You control whether the camera is disabled by using the +{@link android.app.admin.DevicePolicyManager#setCameraDisabled(android.content.ComponentName, boolean) setCameraDisabled()} method. For example, this snippet sets the camera to be enabled or disabled based on a checkbox setting:

    + +
    private CheckBoxPreference mDisableCameraCheckbox;
    +DevicePolicyManager mDPM;
    +ComponentName mDeviceAdminSample;
    +...
    +mDPM.setCameraDisabled(mDeviceAdminSample, mDisableCameraCheckbox.isChecked());
    +
    + +

    Storage encryption

    Beginning with Android 3.0, you can use the {@link android.app.admin.DevicePolicyManager#setStorageEncryption(android.content.ComponentName,boolean) setStorageEncryption()} diff --git a/docs/html/images/admin/device-admin-activate-prompt.png b/docs/html/images/admin/device-admin-activate-prompt.png index 2851194b4b05b..37867880b3933 100644 Binary files a/docs/html/images/admin/device-admin-activate-prompt.png and b/docs/html/images/admin/device-admin-activate-prompt.png differ diff --git a/docs/html/images/admin/device-admin-app.png b/docs/html/images/admin/device-admin-app.png index c96defc266ba6..6b23abaf43a22 100644 Binary files a/docs/html/images/admin/device-admin-app.png and b/docs/html/images/admin/device-admin-app.png differ