【起航计划 019】2015 起航计划 Android APIDemo的魔鬼步伐 18 App->Device Admin 设备管理器 DeviceAdminReceiver DevicePolicyManager PreferenceActivity的使用
2015-03-06 11:13
656 查看
Device Admin示例介绍了类DeviceAdminReceiver,DevicePolicyManager和ActivityManager。
使用DevicePolicyManager这个类,这个类可以接管手机的应用权限,对手机做出很多大胆的操作,比如锁屏、恢复出厂设置、设置密码、强制清除密码,修改密码、设置屏幕灯光渐暗时间间隔等操作。
当它Publish在AndroidManifest.xml作为BroadcastReceiver定义时,必须处理 android.app.action.DEVICE_ADMIN_ENABLED和设置 android.permission.BIND_DEVICE_ADMIN权限,来监听权限的变化:
Android:permission 表示此功能需要的权限。
Android:name="android.app.action.DEVICE_ADMIN_ENABLED"表示此动作的跳转界面。
<meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_sample" />表示这个应用可以管理的权限清单,对应的device_admin_sample如下:
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
<expire-password />
<encrypted-storage />
<disable-camera />
<disable-keyguard-features /> <!--锁屏时禁用某些功能>
</uses-policies>
</device-admin>[/code]
在你设计你的设备管理程序时,并不需要包括所有的安全策略,按需定制即可。
更多WIKI见:链接
在例子程序里,我们只是简单地显示了一个Toast,来做为对相应事件的应答。例如:
比如onPasswordExpiring中,当密码过期时,通过DevicePolicyManager的getPasswordExpiration方法获取过期的时间与当前时间对比。
DeviceAdminSample.java这个类继承自PreferenceActivity。
PreferenceActivity 继承自ListActivity 它是以一个列表的形式在展现内容,它最主要的特点是添加Preference可以让控件的状态持久化储存,举个例子 比如用户选中checkbox后 退出应用然后在进入应用,这时用户希望看到的是checkbox被选中,所以软件须要记录用户每次操作的过程并且持久储存,在进入应用的时候须要判断这些 久储存的数据然后将系统控件的状态呈现在UI中。
需要重写onBuilderHeaders来展示列表,loadHeadersFromResource是PreferenceActivity的方法,用来读取headers:
其中R.xml.device_admin_headers如下:
点击各个条目会进入到对应的PreferenceFragment中:
这里先定义了一个基类AdminSampleFragment,它做了两件事:
1.提供context实例变量和DevicePolicyManager对象
2.针对多个fragment中存在的set password按钮的点击事件进行处理
接下来就是各个子PreferenceFragment了。
对应的PreferenceScreen布局如下:
其他组件见:链接
当用户点击了Enable Admin 选择框,设备就会提示用户已经启用了设备管理程序,
下面就是当用户点击了 Enable Admin 选择框要执行的代码。效果是触发了onPreferenceChange()回调函数。当用户改变Preference的值时,就会调用这个回调函数。如果用户启用程序,界面就会提示用户正在启用程序,否则就是禁止程序:
当程序要执行一个操作,它要确定管理程序是否已经被启用了。实现的方法就是使用DevicePolicyManager的isAdminActive()方法。要注意的是,DevicePolicyManager的isAdminActive()方法需要一个DeviceAdminReceiver类型的参数。
其他管理策略的代码请见链接的4.2.3管理策略:链接
使用DevicePolicyManager这个类,这个类可以接管手机的应用权限,对手机做出很多大胆的操作,比如锁屏、恢复出厂设置、设置密码、强制清除密码,修改密码、设置屏幕灯光渐暗时间间隔等操作。
当它Publish在AndroidManifest.xml作为BroadcastReceiver定义时,必须处理 android.app.action.DEVICE_ADMIN_ENABLED和设置 android.permission.BIND_DEVICE_ADMIN权限,来监听权限的变化:
<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>
Android:permission 表示此功能需要的权限。
Android:name="android.app.action.DEVICE_ADMIN_ENABLED"表示此动作的跳转界面。
<meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin_sample" />表示这个应用可以管理的权限清单,对应的device_admin_sample如下:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android"> <uses-policies> <limit-password /> [code]<!--设置密码规则 所允许的长度和字符 -->
<watch-login />
<!--监视屏幕解锁尝试次数 -->
<reset-password />
<!--更改屏幕解锁密码-->
<force-lock />
<!--强行锁屏-->
<wipe-data />
<!--清除所有数据(恢复出厂设置) -->
<expire-password />
<!--设置锁定屏幕密码的有效期 -->
<encrypted-storage />
<!--加密存储
指定要加密的存储位置-->
<disable-camera />
<!--禁用摄像头-->
<disable-keyguard-features /> <!--锁屏时禁用某些功能>
</uses-policies>
</device-admin>[/code]
在你设计你的设备管理程序时,并不需要包括所有的安全策略,按需定制即可。
更多WIKI见:链接
完成DeviceAdminReceiver的子类
要创建一个设备管理程序,就要实现一个继承DeviceAdminReceiver的类。DeviceAdminReceiver包含了一系列的回调函数,这些回调函数会在具体的事件发生时被调用。在例子程序里,我们只是简单地显示了一个Toast,来做为对相应事件的应答。例如:
/** * Sample implementation of a DeviceAdminReceiver. Your controller must provide one, * although you may or may not implement all of the methods shown here. * * All callbacks are on the UI thread and your implementations should not engage in any * blocking operations, including disk I/O. */ public static class DeviceAdminSampleReceiver 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 onReceive(Context context, Intent intent) { if (intent.getAction() == ACTION_DEVICE_ADMIN_DISABLE_REQUESTED) { abortBroadcast(); } super.onReceive(context, intent); } @Override 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 context.getString(R.string.admin_receiver_status_disable_warning); } @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, context.getString(R.string.admin_receiver_status_pw_changed)); } @Override public void onPasswordFailed(Context context, Intent intent) { showToast(context, context.getString(R.string.admin_receiver_status_pw_failed)); } @Override public void onPasswordSucceeded(Context context, Intent intent) { showToast(context, context.getString(R.string.admin_receiver_status_pw_succeeded)); } @Override public void onPasswordExpiring(Context context, Intent intent) { DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService( Context.DEVICE_POLICY_SERVICE); long expr = dpm.getPasswordExpiration( new ComponentName(context, DeviceAdminSampleReceiver.class)); long delta = expr - System.currentTimeMillis(); boolean expired = delta < 0L; String message = context.getString(expired ? R.string.expiration_status_past : R.string.expiration_status_future); showToast(context, message); Log.v(TAG, message); } }
比如onPasswordExpiring中,当密码过期时,通过DevicePolicyManager的getPasswordExpiration方法获取过期的时间与当前时间对比。
DeviceAdminSample.java这个类继承自PreferenceActivity。
PreferenceActivity 继承自ListActivity 它是以一个列表的形式在展现内容,它最主要的特点是添加Preference可以让控件的状态持久化储存,举个例子 比如用户选中checkbox后 退出应用然后在进入应用,这时用户希望看到的是checkbox被选中,所以软件须要记录用户每次操作的过程并且持久储存,在进入应用的时候须要判断这些 久储存的数据然后将系统控件的状态呈现在UI中。
需要重写onBuilderHeaders来展示列表,loadHeadersFromResource是PreferenceActivity的方法,用来读取headers:
/** * We override this method to provide PreferenceActivity with the top-level preference headers. */ @Override public void onBuildHeaders(List<Header> target) { loadHeadersFromResource(R.xml.device_admin_headers, target); }
其中R.xml.device_admin_headers如下:
<!--Headers for a set of preferences used to exercise the DevicePolicyManager API. -->
<preference-headers
xmlns:android="http://schemas.android.com/apk/res/android" >
<header
android:fragment="com.example.android.apis.app.DeviceAdminSample$GeneralFragment"
android:title="@string/header_general" />
<header
android:fragment="com.example.android.apis.app.DeviceAdminSample$QualityFragment"
android:title="@string/header_quality" />
<header
android:fragment="com.example.android.apis.app.DeviceAdminSample$ExpirationFragment"
android:title="@string/header_expiration" />
<header
android:fragment="com.example.android.apis.app.DeviceAdminSample$LockWipeFragment"
android:title="@string/header_lock_wipe" />
<header
android:fragment="com.example.android.apis.app.DeviceAdminSample$EncryptionFragment"
android:title="@string/header_encryption" />
</preference-headers>
点击各个条目会进入到对应的PreferenceFragment中:
这里先定义了一个基类AdminSampleFragment,它做了两件事:
1.提供context实例变量和DevicePolicyManager对象
2.针对多个fragment中存在的set password按钮的点击事件进行处理
/** * Common fragment code for DevicePolicyManager access. Provides two shared elements: * * 1. Provides instance variables to access activity/context, DevicePolicyManager, etc. * 2. Provides support for the "set password" button(s) shared by multiple fragments. */ public static class AdminSampleFragment extends PreferenceFragment implements OnPreferenceChangeListener, OnPreferenceClickListener
接下来就是各个子PreferenceFragment了。
GeneralFragment
调用addPreferencesFromResource展示列表,findPreference获取各个列表对象并设置监听:@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.device_admin_general); mEnableCheckbox = (CheckBoxPreference) findPreference(KEY_ENABLE_ADMIN); mEnableCheckbox.setOnPreferenceChangeListener(this); mDisableCameraCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_CAMERA); mDisableCameraCheckbox.setOnPreferenceChangeListener(this); mDisableKeyguardWidgetsCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_KEYGUARD_WIDGETS); mDisableKeyguardWidgetsCheckbox.setOnPreferenceChangeListener(this); mDisableKeyguardSecureCameraCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_KEYGUARD_SECURE_CAMERA); mDisableKeyguardSecureCameraCheckbox.setOnPreferenceChangeListener(this); mDisableKeyguardNotificationCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_NOTIFICATIONS); mDisableKeyguardNotificationCheckbox.setOnPreferenceChangeListener(this); mDisableKeyguardUnredactedCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_UNREDACTED); mDisableKeyguardUnredactedCheckbox.setOnPreferenceChangeListener(this); mDisableKeyguardTrustAgentCheckbox = (CheckBoxPreference) findPreference(KEY_DISABLE_TRUST_AGENTS); mDisableKeyguardTrustAgentCheckbox.setOnPreferenceChangeListener(this); }
对应的PreferenceScreen布局如下:
<!--A set of preferences used to exercise the DevicePolicyManager API. -->
<!--This screen is shown for the "General" header. -->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="@string/enable_admin" >
<CheckBoxPreference
android:key="key_enable_admin"
android:title="@string/enable_admin" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/device_capabilities_category" >
<CheckBoxPreference
android:key="key_disable_camera"
android:title="@string/disable_camera" />
<CheckBoxPreference
android:key="key_disable_keyguard_widgets"
android:title="@string/disable_keyguard_widgets" />
<CheckBoxPreference
android:key="key_disable_keyguard_secure_camera"
android:title="@string/disable_keyguard_secure_camera" />
<CheckBoxPreference
android:key="key_disable_notifications"
android:title="@string/disable_keyguard_notifications" />
<CheckBoxPreference
android:key="key_disable_unredacted"
android:title="@string/disable_keyguard_unredacted_notifications" />
<CheckBoxPreference
android:key="key_disable_trust_agents"
android:title="@string/disable_keyguard_trust_agents" />
</PreferenceCategory>
</PreferenceScreen>
PreferenceScreen:代表显示一整个屏幕
PreferenceCategory:内部嵌套PreferenceCategory标签,表示偏好类别,在PreferenceCategory标签内部可以随便存放复选框CheckBoxPreference,输入框EditTextPreference,列表ListPreference等显示控件
CheckBoxPreference:复选框控件
其他组件见:链接
当用户点击了Enable Admin 选择框,设备就会提示用户已经启用了设备管理程序,
下面就是当用户点击了 Enable Admin 选择框要执行的代码。效果是触发了onPreferenceChange()回调函数。当用户改变Preference的值时,就会调用这个回调函数。如果用户启用程序,界面就会提示用户正在启用程序,否则就是禁止程序:
@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; }
当程序要执行一个操作,它要确定管理程序是否已经被启用了。实现的方法就是使用DevicePolicyManager的isAdminActive()方法。要注意的是,DevicePolicyManager的isAdminActive()方法需要一个DeviceAdminReceiver类型的参数。
DevicePolicyManager mDPM; ... private boolean isActiveAdmin() { return mDPM.isAdminActive(mDeviceAdminSample); }
其他管理策略的代码请见链接的4.2.3管理策略:链接
相关文章推荐
- 【起航计划 019】2015 起航计划 Android APIDemo的魔鬼步伐 18 App-&gt;Device Admin 设备管理器 DeviceAdminReceiver DevicePolicyManager PreferenceActivit
- 【起航计划 008】2015 起航计划 Android APIDemo的魔鬼步伐 07 App->Activity->Persistent State 保存状态 SharedPreferences onPause onResume
- 【起航计划 009】2015 起航计划 Android APIDemo的魔鬼步伐 08 App-&gt;Activity-&gt;QuickContactsDemo 联系人 ResourceCursorAdapter使用 QuickContactBad
- 【起航计划 028】2015 起航计划 Android APIDemo的魔鬼步伐 27 App->Preferences->Launching preferences 其他activity获取Preference中的值
- 【起航计划 028】2015 起航计划 Android APIDemo的魔鬼步伐 27 App-&gt;Preferences-&gt;Launching preferences 其他activity获取Preference中的值
- 【起航计划 005】2015 起航计划 Android APIDemo的魔鬼步伐 04 App-&gt;Activity-&gt;Custom Dialog Dialog形式的Activity,Theme的使用,Shape的使用
- 【起航计划 009】2015 起航计划 Android APIDemo的魔鬼步伐 08 App->Activity->QuickContactsDemo 联系人 ResourceCursorAdapter使用 QuickContactBadge使用
- 【起航计划 005】2015 起航计划 Android APIDemo的魔鬼步伐 04 App->Activity->Custom Dialog Dialog形式的Activity,Theme的使用,Shape的使用
- 【起航计划 013】2015 起航计划 Android APIDemo的魔鬼步伐 12 App->Activity->SetWallpaper 设置壁纸 WallpaperManager getDrawingCache使用
- 【起航计划 008】2015 起航计划 Android APIDemo的魔鬼步伐 07 App-&gt;Activity-&gt;Persistent State 保存状态 SharedPreferences onPause onResume
- 【起航计划 013】2015 起航计划 Android APIDemo的魔鬼步伐 12 App-&gt;Activity-&gt;SetWallpaper 设置壁纸 WallpaperManager getDrawingCache使用
- 【起航计划 007】2015 起航计划 Android APIDemo的魔鬼步伐 06 App->Activity->Forwarding Activity启动另外一个Activity finish()方法
- 【起航计划 025】2015 起航计划 Android APIDemo的魔鬼步伐 24 App->Notification->Notifying Service Controller service中使用Notification
- 【起航计划 010】2015 起航计划 Android APIDemo的魔鬼步伐 09 App->Activity->Redirection 根据shared preferences是否有值决定是否redirect
- 【起航计划 027】2015 起航计划 Android APIDemo的魔鬼步伐 26 App->Preferences->Preferences from XML 偏好设置界面
- 【起航计划 014】2015 起航计划 Android APIDemo的魔鬼步伐 13 App->Activity->Translucent 半透明Activity Theme.Translucent
- 【起航计划 006】2015 起航计划 Android APIDemo的魔鬼步伐 05 App->Activity->Custom Title 自定义标题栏
- 【起航计划 022】2015 起航计划 Android APIDemo的魔鬼步伐 21 App->Launcher Shortcuts 为某个非主Activity在Home Screen上建立一个快捷方式
- 【起航计划 033】2015 起航计划 Android APIDemo的魔鬼步伐 32 App->Service->Foreground Service Controller service使用,共享service,前台服务,onStartCommand
- 【起航计划 023】2015 起航计划 Android APIDemo的魔鬼步伐 22 App->Menu->Inflate from XML 使用xml资源展示菜单