【起航计划 019】2015 起航计划 Android APIDemo的魔鬼步伐 18 App->Device Admin 设备管理器 DeviceAdminReceiver DevicePolicyManager PreferenceActivity的使用
Device Admin示例介绍了类DeviceAdminReceiver,DevicePolicyManager和ActivityManager。
使用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 /><!-- 设置密码规则 所允许的长度和字符 -->
<watch-login /><!-- 监视屏幕解锁尝试次数 -->
<reset-password /><!--
更改屏幕解锁密码
-->
<force-lock /><!-- 强行锁屏-->
<wipe-data /><!-- 清除所有数据(恢复出厂设置) -->
<expire-password /><!-- 设置锁定屏幕密码的有效期 -->
<encrypted-storage /><!--
加密存储指定要加密的存储位置-->
<disable-camera /><!-- 禁用摄像头-->
<disable-keyguard-features /> <!--锁屏时禁用某些功能>
</uses-policies>
</device-admin>
在你设计你的设备管理程序时,并不需要包括所有的安全策略,按需定制即可。
更多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->Device Admin 设备管理器 DeviceAdminReceiver DevicePolicyManager PreferenceActivity的使用的更多相关文章
- 【起航计划 002】2015 起航计划 Android APIDemo的魔鬼步伐 01
本文链接:[起航计划 002]2015 起航计划 Android APIDemo的魔鬼步伐 01 参考链接:http://blog.csdn.net/column/details/mapdigitap ...
- 【起航计划 037】2015 起航计划 Android APIDemo的魔鬼步伐 36 App->Service->Remote Service Binding AIDL实现不同进程间调用服务接口 kill 进程
本例和下个例子Remote Service Controller 涉及到的文件有RemoteService.java ,IRemoteService.aidl, IRemoteServiceCallb ...
- 【起航计划 031】2015 起航计划 Android APIDemo的魔鬼步伐 30 App->Preferences->Advanced preferences 自定义preference OnPreferenceChangeListener
前篇文章Android ApiDemo示例解析(31):App->Preferences->Launching preferences 中用到了Advanced preferences 中 ...
- 【起航计划 027】2015 起航计划 Android APIDemo的魔鬼步伐 26 App->Preferences->Preferences from XML 偏好设置界面
我们在前面的例子Android ApiDemo示例解析(9):App->Activity->Persistent State 介绍了可以使用Shared Preferences来存储一些状 ...
- 【起航计划 020】2015 起航计划 Android APIDemo的魔鬼步伐 19 App->Dialog Dialog样式
这个例子的主Activity定义在AlertDialogSamples.java 主要用来介绍类AlertDialog的用法,AlertDialog提供的功能是多样的: 显示消息给用户,并可提供一到三 ...
- 【起航计划 012】2015 起航计划 Android APIDemo的魔鬼步伐 11 App->Activity->Save & Restore State onSaveInstanceState onRestoreInstanceState
Save & Restore State与之前的例子Android ApiDemo示例解析(9):App->Activity->Persistent State 实现的UI类似,但 ...
- 【起航计划 003】2015 起航计划 Android APIDemo的魔鬼步伐 02 SimpleAdapter,ListActivity,PackageManager参考
01 API Demos ApiDemos 详细介绍了Android平台主要的 API,android 5.0主要包括下图几个大类,涵盖了数百api示例:
- 【起航计划 035】2015 起航计划 Android APIDemo的魔鬼步伐 34 App->Service->Local Service Controller
Local Service Controller 是将LocalService当作“Started”Service来使用,相对于”Bound” Service 来说,这种模式用法要简单得多,Local ...
- 【起航计划 034】2015 起航计划 Android APIDemo的魔鬼步伐 33 App->Service->Local Service Binding 绑定服务 ServiceConnection Binder
本例和下列Local Service Controller 的Activity代码都定义在LocalServiceActivities.Java 中,作为LocalServiceActivities ...
随机推荐
- 数据结构11: 栈(Stack)的概念和应用及C语言实现
栈,线性表的一种特殊的存储结构.与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的. 图1 栈结构示意图 由于栈只有一边开口存取数据,称开口的那一端为“栈顶”, ...
- html5 语音识别 转
- vue 学习一
这个是很早之前公司要使用vue.js时候学习记在有道云笔记上的,发觉那个笔记贼多了,没办法,觉得是要换个地方存笔记了, 一vue.js的使用: 可以在页面是直接使用: <!DOCTYPE htm ...
- jeesite 框架的简单应用
个人觉得比较完善的一个讲解jeesite的网站 https://www.w3cschool.cn/jeesite/ jeesite官网 http://jeesite.com/ 公司项目都是基于jees ...
- CSS(十三).高度如何铺满全屏
该需求来源一次面试题. IE6不认识!important声明,IE7.IE8.Firefox.Chrome等浏览器认识:而在怪异模式中,IE6/7/8都不认识!important声明,这只是区别的一种 ...
- java mybatis学习一
1.引入maven包 和 导入 sqljdbc包 <dependency> <groupId>org.apache.ibatis</groupId> <art ...
- photoshop特效字体
一.3D效果字 3D效果文字给人以纵伸感.立体感和真实感,是商家常用到的一种宣传文字.虽然Photoshop软件是平面软件,但是在制作3D效果文字时却游刃有余. 3D效果字的制作可分以下三步完成. 输 ...
- hdu1387 模拟队列
Team Queue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- 阿里云 Ubuntu14.04 部署 LAMP
1.更新软件源 sudo apt-get update 2.安装Apache sudo apt-get install apache2 3.查看Apache是否安装成功 apache2 –v 如下所示 ...
- 将tomcat的protocol改为APR模式,以提高性能
以下是我修改的内容,以及对tomcat可以修改的参数 scm APR模式启动步骤: 1:将附件中的压缩包,在/usr/local 下解压 2:修改../bin/catalina.sh ,在其 ...