Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d77ad80 authored by Katie McCormick's avatar Katie McCormick Committed by Android Git Automerger
Browse files

am 6c5951bf: Doc change: Updating device-admin with camera info.

* commit '6c5951bf':
  Doc change: Updating device-admin with camera info.
parents 943f6d0b 6c5951bf
Loading
Loading
Loading
Loading
+118 −129
Original line number Diff line number Diff line
@@ -27,6 +27,12 @@ page.title=Device Administration
      <li>{@link android.app.admin.DevicePolicyManager}</li>
      <li>{@link android.app.admin.DeviceAdminInfo}</li>
    </ol>
    <h2>Related samples</h2>
    <ol>
      <li><a
href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html">
DeviceAdminSample</a></li>
</ol>
</div>
</div>

@@ -201,6 +207,16 @@ access data. The value can be between 1 and 60 minutes.</td> </tr>
<td>Specifies that the storage area should be encrypted, if the device supports it. 
Introduced in Android 3.0.</td> </tr>

<tr>
  <td>Disable camera</td>
  
  <td>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.</td>
  
</tr>


</table>

<h4>Other features</h4>
@@ -247,6 +263,7 @@ one of the last <em>n</em> passwords they previously used.</li>
locks.</li>
  <li>Make the device lock immediately.</li>
  <li>Wipe the device's data (that is, restore factory settings).</li>
  <li>Disable the camera.</li>
  
</ul>

@@ -280,46 +297,38 @@ intent, expressed in the manifest as an intent filter.</li>
  <li>A declaration of security policies used in metadata.</li>
</ul>
<p>Here is an excerpt from the Device Administration sample manifest:</p>
<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample$Controller&quot;
          android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
    &lt;/intent-filter&gt;
<pre>&lt;activity android:name=&quot;.app.DeviceAdminSample&quot;
            android:label=&quot;&#64;string/activity_sample_device_admin&quot;&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
        &lt;category android:name=&quot;android.intent.category.SAMPLE_CODE&quot; /&gt;
    &lt;/intent-filter&gt;
&lt;/activity&gt;

&lt;receiver android:name=&quot;.app.DeviceAdminSample&quot;
          android:label=&quot;&#64;string/sample_device_admin&quot;
          android:description=&quot;&#64;string/sample_device_admin_description&quot;
          android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
               android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
    &lt;/intent-filter&gt;
&lt;receiver android:name=&quot;.app.DeviceAdminSample$DeviceAdminSampleReceiver&quot;
        android:label=&quot;&#64;string/sample_device_admin&quot;
        android:description=&quot;&#64;string/sample_device_admin_description&quot;
        android:permission=&quot;android.permission.BIND_DEVICE_ADMIN&quot;&gt;
    &lt;meta-data android:name=&quot;android.app.device_admin&quot;
            android:resource=&quot;&#64;xml/device_admin_sample&quot; /&gt;
    &lt;intent-filter&gt;
        &lt;action android:name=&quot;android.app.action.DEVICE_ADMIN_ENABLED&quot; /&gt;
    &lt;/intent-filter&gt;
&lt;/receiver&gt;</pre>

 <p>Note that:</p>
<ul>
  <li>The activity in the sample application is an {@link android.app.Activity}
subclass called <code>Controller</code>. The syntax
<code>&quot;.app.DeviceAdminSample$Controller&quot;</code>  indicates that
<code>Controller</code> is an inner class that is nested inside the
<code>DeviceAdminSample</code> class. Note that an Activity does not need to be
an inner class; it just is in this example.</li>

<li>The following attributes refer to string resources that for the sample application reside in
<code>ApiDemos/res/values/strings.xml</code>. For more information about resources, see
<a
href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.
<ul>
<li><code>android:label=&quot;@string/activity_sample_device_admin&quot;</code> refers to the
<li><code>android:label=&quot;&#64;string/activity_sample_device_admin&quot;</code> refers to the
user-readable label for the activity.</li>

<li><code>android:label=&quot;@string/sample_device_admin&quot;</code> refers to the
<li><code>android:label=&quot;&#64;string/sample_device_admin&quot;</code> refers to the
user-readable label for the permission.</li>

<li><code>android:description=&quot;@string/sample_device_admin_description&quot;</code> refers to
<li><code>android:description=&quot;&#64;string/sample_device_admin_description&quot;</code> refers to
the user-readable description of the permission. A descripton is typically longer and more
informative than
a label.</li>
@@ -357,6 +366,9 @@ android.app.admin.DeviceAdminInfo} class. Here are the contents of
    &lt;reset-password /&gt;
    &lt;force-lock /&gt;
    &lt;wipe-data /&gt;
    &lt;expire-password /&gt;
    &lt;encrypted-storage /&gt;
    &lt;disable-camera /&gt;
  &lt;/uses-policies&gt;
&lt;/device-admin&gt;
</pre>
@@ -401,33 +413,34 @@ simply displays a {@link android.widget.Toast} notification in response to parti
events. For example:</p>
<pre>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();
    }

    &#64;Override
    public void onEnabled(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: enabled&quot;);
    }

    &#64;Override
    public CharSequence onDisableRequested(Context context, Intent intent) {
        return &quot;This is an optional message to warn the user about disabling.&quot;;
    }

    &#64;Override
    public void onDisabled(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: disabled&quot;);
    }

    &#64;Override
    public void onPasswordChanged(Context context, Intent intent) {
        showToast(context, &quot;Sample Device Admin: pw changed&quot;);
    }

    void showToast(Context context, CharSequence msg) {
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
    public void onEnabled(Context context, Intent intent) {
        showToast(context, context.getString(R.string.admin_receiver_status_enabled));
    }

    &#64;Override
    public CharSequence onDisableRequested(Context context, Intent intent) {
        return context.getString(R.string.admin_receiver_status_disable_warning);
    }

    &#64;Override
    public void onDisabled(Context context, Intent intent) {
        showToast(context, context.getString(R.string.admin_receiver_status_disabled));
    }

    &#64;Override
    public void onPasswordChanged(Context context, Intent intent) {
        showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
    }
...
}</pre>


<h4 id="enabling">Enabling the application</h4>
<p>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,44 +451,51 @@ get any of the application's benefits.</p>
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 <strong>Enable
Admin</strong> button. </p>
<p>When the user clicks the <strong>Enable Admin</strong> button, the display
changes to prompt the user to enable the device admin application, as shown in figure
Admin</strong> checkbox. </p>
<p>When the user clicks the <strong>Enable Admin</strong> checkbox, the display
changes to prompt the user to activate the device admin application, as shown in figure
2.</p>

<img src="{@docRoot}images/admin/device-admin-activate-prompt.png"/>
<p class="img-caption"><strong>Figure 2.</strong> Sample Application: Activating the Application</p>
<p>Below  is the code that gets executed when the user clicks the <strong>Enable
Admin</strong> button shown in figure 1. </p>

<pre> private OnClickListener mEnableListener = new OnClickListener() {
    public void onClick(View v) {
<p>Below  is the code that gets executed when the user clicks the <strong>Enable Admin</strong> 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. </p>

<pre>&#64;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,
               &quot;Additional text explaining why this needs to be added.&quot;);
        startActivityForResult(intent, RESULT_ENABLE);
                        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);
                ...
// This code checks whether the device admin app was successfully enabled.
&#64;Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case RESULT_ENABLE:
            if (resultCode == Activity.RESULT_OK) {
                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enabled!&quot;);
            } else {
                Log.i(&quot;DeviceAdminSample&quot;, &quot;Administration enable FAILED!&quot;);
            }
            return;
    }
    super.onActivityResult(requestCode, resultCode, data);
            }
            return true;
        }</pre>


<p>The line
<code>intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mDeviceAdminSample)</code> states that <code>mDeviceAdminSample</code> (which is
@@ -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:</p>

<pre>
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);
}
</pre>



<h3 id="admin_ops">Managing policies</h3>
<p>{@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
@@ -619,49 +638,6 @@ long pwExpiration;
mDPM.setPasswordExpirationTimeout(mDeviceAdminSample, pwExpiration);
</pre>
    
<p>From the <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/DeviceAdminSample.html"
>Device Administration API sample</a>, here is the code
that updates the password expiration status:</p>

<pre>
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 &gt;= 0) {
            statusText = &quot;Expiration in &quot; + countdownString(mSecUntilExpiration);
        } else {
            statusText = &quot;Expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
        }

        // expirationTimeout is the cycle time between required password refresh
        long expirationTimeout = mDPM.getPasswordExpirationTimeout(mDeviceAdminSample);
        statusText += &quot; / timeout period &quot; + countdownString(expirationTimeout);

        // Now report the aggregate (global) expiration time
        statusText += &quot; / Aggregate &quot;;
        expirationDate = mDPM.getPasswordExpiration(null);
        mSecUntilExpiration = expirationDate - now;
        if (mSecUntilExpiration &gt;= 0) {
            statusText += &quot;expiration in &quot; + countdownString(mSecUntilExpiration);
        } else {
            statusText += &quot;expired &quot; + countdownString(-mSecUntilExpiration) + &quot; ago&quot;;
        }
    } else {
        statusText = &quot;&lt;inactive&gt;&quot;;
    }
    mPasswordExpirationStatus.setText(statusText);</pre>
    
<h5 id="history">Restrict password based on history</h5>

<p>Beginning with Android 3.0, you can use the 
@@ -718,6 +694,19 @@ mDPM.wipeData(0);</pre>
<p>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. </p>

<h4>Disable camera</h4>
<p>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. </p>
<p>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:</p>

<pre>private CheckBoxPreference mDisableCameraCheckbox;
DevicePolicyManager mDPM;
ComponentName mDeviceAdminSample;
...
mDPM.setCameraDisabled(mDeviceAdminSample, mDisableCameraCheckbox.isChecked());<br />
</pre>


<h4 id=storage">Storage encryption</h4>
<p>Beginning with Android 3.0, you can use the 
{@link android.app.admin.DevicePolicyManager#setStorageEncryption(android.content.ComponentName,boolean) setStorageEncryption()} 
−522 B (89.9 KiB)
Loading image diff...
−261 KiB (28.6 KiB)
Loading image diff...