From 6c5951bf9798369d335096f1f73ee1299cf903ff Mon Sep 17 00:00:00 2001
From: Katie McCormick Here is an excerpt from the Device Administration sample manifest: Note that:Related samples
+
@@ -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.
<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>
-
Controller. The syntax
-".app.DeviceAdminSample$Controller" indicates that
-Controller is an inner class that is nested inside the
-DeviceAdminSample class. Note that an Activity does not need to be
-an inner class; it just is in this example.ApiDemos/res/values/strings.xml. For more information about resources, see
Application Resources.
-
android:label="@string/activity_sample_device_admin" refers to the
+android:label="@string/activity_sample_device_admin" refers to the
user-readable label for the activity.android:label="@string/sample_device_admin" refers to the
+android:label="@string/sample_device_admin" refers to the
user-readable label for the permission.android:description="@string/sample_device_admin_description" refers to
+android:description="@string/sample_device_admin_description" refers to
the user-readable description of the permission. A descripton is typically longer and more
informative than
a label.
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));
}
...
}
+
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);
}
+
+
{@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);
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.
+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());+ +
+
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 2851194b4b05b7f13266d832abfb5819aea5652b..37867880b393348a2502af8fb64846079ca7cbcc 100644
GIT binary patch
literal 92009
zcmYg%2RPO58}~7?A~H|5l2OPeWQC0E$lg19udM7nitHVcy$MA&NeI~?D|_$v_Iuy|
zb-mx~>ZIeG@ArA`=N_NW=e`S5Qh0`kLym($An;_QB~%aylvwz)iG>R92p `3VV8
z5vY1MJ@6_5v!z7-k#XVvSn-SK!R9%Q6QLVfK` #yD%J|kE6F^Q$^vp0=!^M@rLVzS8;Q^YL
zmPQ$DDD5hq&;uPb0P-*`6dDsuAS*2`EhEE$#Qhdahpht|hg`1%KP9XcYNtuEQ`N-t
zL?Ja|Q2xT`y gf7R{Ex@elh)0w)dSyFRF&w{bPeIn=&P)TJj%|HG}?xA6`
zEk9%GGTjK>ZOxK3=POt4)XUP$63Z&V)^be5z=~(QL##-~VX*nJP1lZ cWj@2Wg%`zAt&f!7S)LsnaZC5V^5u&%=AUu?$>@E=
z_7r_~jrV0Z9oA-4jMNwh|KUj!Og(lAs9b@!++|f(T9+)|r7d-LYiH1j)8)&1FY?js
zWhZSK^I_98iMZMfQIo3&BMujegm|s7+&6qq+GAN21JiJ)UK%o5EznY?roCF`%n9i7
z$#YAolsK-Rnj)?*vScua_*v1V{hNDRZ}F0U=pi^)D=D&IFZPU$SqeEPOzRfby>Z*{
zr&_jtU*CgWJ+_A )h;VOUg3w8t@>5mp5VqGGEUKgG_V3qkC`|`r22>;n
z4TQRfY;=HMgU6*r>In`^vrutxb0A33E7k{9O`?l}WgFy5-*^~fbVP2r6^Qoa?7_ap
zlv2x-I^R6b3f_Z?OiA3cLSL*An1K20RDF)@qP=-MMVFhii(Pp
zeH%)FGehIYc8MGA`0WqU!}=_($>kJgk|Gp?o=f%jQ6_GD5qzbCgIr$bi4!OEmG@e!
z@7c2l+l=7HpfgXb94}qJj+o5|i-Wqlg;pHT4#>Q>4E}-f_z5agBHVO7JvkHWpy}=H
z{q6gA8n24D<(0bP@&?*@nH7=shau|#KBc?O9N|eHEzkba^&9C|h=Ah*%QaaTMRhCJ
ztf9^4i1N+5j>hW5iCZmx6bGWy2Z%Ykxk<0nQr?SdO l4j+`+O&u!C%ekB?k<$GLGskJ*iuPYmkFLS?6|{ei8w
zQ%o*@#SKmgBeEiB=h(Q%$ykM72RHh6)hcDWOC}oX6V-U+!
z?b40B*zi6Z)2Ob(PEKifm939eyB~UXne&43uI#pVdGJzT0Ex~aYB!GKsB+eUJx^`@
zx7D^OmmiD-+Ku0uebtMi#l(J0?Gp)&uTPyk?B3CE#<|JMKELz5uC_8vQ+!5ca?kB)
zw*lh)9FyT?iM51K;{B6u%%A?c8jh$4+OC@?eJ86o{b-pEmi}Ot<;=KZ-BC+03Pe7l
z8ThQ7oX66QE!%Esx#gN)bBmM3K!eT>JE;a?CA7F!HWylrWNve*6Bmo
RlZJOq)q}g52%(*kA;rnNoI>`<=4D5y+e>PQm6{|>vVCizljO83^
zklkqP%3FD{(>&XwzhTNqzwW!6`18eA3`yo`*6-=9sGl*q3FpvZSyVESw=>g
zne7Q3e)`AIjA9)QU
zSD17pnOk>)8zQ$T%`;DXOlFy?$cn#dgn{f^gnVyQjgPKA>{%_ve_}AEV}R`W@afZt
zp+k}VIcZ84mI{}J_p_|O*`%pt3tvJ%XQ!Z2LbJy&J?GJbP`flp8gyVVRaTakKfAin
zISD&VF*ALA{cmlrrU?YNp;qw_&ewRB4!P!2C)&K4c(3j32X4&Doz>Z$5RbTZ;s|;9
zl sZX;>Csn-9$TP>a@LbE3
zF*}Hdadv+4Deqq3fzw9sOXr;EJ-YE{a?y(R!4BTvIn1@S|1;dE@aKgDe$x?jLFnTM
zj$XL125EM|!V!LtlCD?|zxttYfls%U+)nhLi=^8hJ{sm%mD-|sq&$4
aP(gNb&+_PRV*CN6F!#BRWT*N#+F%&F5FlrsHzxC_a-&{H%uR`DhUNXe_^Kj{$
zet-G1PF-Ay|wOp4x>=KCB$Y=gX>mmOSQIr9Yu-c!K;jH6~~73YxP#FNp5eoj=Ry
zAW-=>z0BtgT=wij6!QHfr_gCHFD=szv+>9c#36BWij