您的位置:首页 > 移动开发 > Android开发

Android Api Demos登顶之路(三十四)Device Admin

2015-08-17 21:25 483 查看
这个demo演示了如何利用设备管理器,实现对系统设备的配置,比如重新设置密码规则、锁屏、清除数据等操作。

这里有几个知识点需要注意:

一是preferenceActivity。PreferenceActivity 继承ListActivity 它是以一个列表的形式在展现内容,它最主要的特点是添加Preference可以让控件的状态持久化储存,举个例子 比如用户选中checkbox后 退出应用然后在进入应用,这时用户希望看到的是checkbox被选中,所以软件须要记录用户每次操作的过程并且持久储存,在进入应用的时候须要判断这些久储存的数据然后将系统控件的状态呈现在UI中。在软件开发的设置选项中它用来专门解决这些特殊的选项保存与读取的显示。用户每次操作事件它会及时的以键值对的形式记录在SharedPreferences中,Activity每次启动它会自动帮我们完成数据的读取以及UI的显示。大家可以参考android系统的设置界面。

二是DevicePolicyManager。这是设备管理的主类。通过它可以实现屏幕锁定、屏幕亮度调节、出厂设置等功能。

三是DeviceAdminReceiver。 该类继承自 BroadcastReceiver 。 从源码可以看到,其实就是实现了一个OnReceive方法,该方法中根据不同的Action,执行相应的操作。用以监听设备权限的变化并,根据权限的变化做出相应的处理。

实现步骤:

1.让MainActivity实现preferenceActivity。

2.定义MainActivity的布局文件:preference_header.xml

Android 3.0之后,摈弃了传统的 PreferenceScreen 嵌套方法,而是采用了所谓的 Preference Headers 方法,该方法的要点是:在主屏中通过 headers xml 文件布局列出所有的主题设置项,而每个主题设置的详细设置则由各自指定的 PreferenceFragment 负责.方便同一个应用在不同屏幕大小的设备中进行适配.

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" >
<header
android:fragment="com.fishtosky.deviceadmin.MainActivity$GeneralFragment"
android:title="General"/>
<header
android:fragment="com.fishtosky.deviceadmin.MainActivity$PasswordQualityFragment"
android:title="Password Quality"/>
<header
android:fragment="com.fishtosky.deviceadmin.MainActivity$PasswordExpirationFragment"
android:title="Password Expiration"/>
<header
android:fragment="com.fishtosky.deviceadmin.MainActivity$LockSecreenAndWipeFragment"
android:title="Lock Screen/Wipe"/>
<header
android:fragment="com.fishtosky.deviceadmin.MainActivity$EncryptionFragment"
android:title="Encryption"/>
</preference-headers>


$表示为内部类。

3.创建DeviceAdminReceiver的子类,这里也定义了一个内部类

并在配置文件中进行配置。

<!-- 为服务声明管理和操作设备的权限 -->
<receiver
android:name="com.fishtosky.deviceadmin.MainActivity$MyAdminReceiver"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<!--  列出该应用可以管理的权限清单 -->
<meta-data android:name="android.app.device_admin"
android:resource="@xml/device_admin_policies"/>
<!-- 一个困扰许久的问题:为什么要在此处设置这个动作过滤器,而只设置这一个动作过滤器,而不需要设置其它的过滤器。
通过分析源代码:这个动作是一个最主要的动作如果想要使用应用实现对设备的管理,就必须执行这个动作。为了不使其它应用也随意
使用这个动作必须给receiver添加BIND_DEVICE_ADMIN权限。当用户激活允许对系统设备进行管理的按钮时,这个动作就会被
广播出去,系统就会根据这个动作寻找能够处理该动作的广播。从而找到这个广播接收者,而在此应用中关于设备管理器其它的权限修改
和设置的操作,都是在激活设备管理器的基础上进行的,所以其它操作的动作是直接发送给这个设备管理者的而不必再去花费功夫寻找合适
的receiver,所以只需要注册一个动作过滤器,注册这个最主要的动作过滤器就可以了 -->
<intent-filter >
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
</intent-filter>
</receiver>


由于这个demo代码量较大,这里简单地实现第一个Fragment供大家参考,其余Fragment功能的实现方式也都大同小意。

GeneralFragment的布局文件:device_admin_general.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:title="Enable admin">
<CheckBoxPreference
android:key="key_enable_admin"
android:title="Enable admin"/>
</PreferenceCategory>
<PreferenceCategory
android:title="Device capabilities">
<CheckBoxPreference
android:key="key_disable_all_camera"
android:title="Disable all device camera"/>
<CheckBoxPreference
android:key="key_disable_keyguard_widgets"
android:title="Disable keyguard widgets"/>
<CheckBoxPreference
android:key="key_disable_keyguard_secure_camera"
android:title="Disable keyguard secure camera"/>
</PreferenceCategory>

</PreferenceScreen>


MainActivity

public class MainActivity extends PreferenceActivity {

private static DevicePolicyManager mDPM;
private static ComponentName mDeviceAdmin;
private static boolean mActiveAdmin;
// 将用户输入的数值转化为时间值
private static long PRE_MINUTES = 60 * 1000;
private static long PRE_HOUR = 60 * PRE_MINUTES;
private static long PRE_DAY = 24 * PRE_HOUR;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mDeviceAdmin = new ComponentName(this, MyAdminReceiver.class);
}

@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference_header, target);
}

/*
* 必须重写该方法,以保证GeneralFragment是一个有效的Fragment,不然会报错
*/
@Override
protected boolean isValidFragment(String fragmentName) {
return true;
}

/*
* 判断设备管理器是否被激活(即我们是否在设备管理器激活界面点击了激活按钮)
*/
private static boolean isActiveAdmin() {
return mDPM.isAdminActive(mDeviceAdmin);
}

/*
* 实现General界面的功能,当在主界面上点击General条目(herader定义的条目)时,进入此界面。
*/
public static class GeneralFragment extends PreferenceFragment implements
OnPreferenceChangeListener {
private static final int REQUEST_CODE_ADMIN_ENABLE = 1;
private static final int KEYGUARD_DISABLE_WIDGET = 11;
private static final int KEYGUARD_ENABLE_WIDGET = 12;
private static final int KEYGUARD_DISABLE_SECURE_CAMERA = 13;
private static final int KEYGUARD_ENABLE_SECURE_CAMERA = 14;
private int flag = DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
private CheckBoxPreference mGeneralAdmin;
private CheckBoxPreference mDisabledAllCamera;
private CheckBoxPreference mDisabledKeyguardWidget;
private CheckBoxPreference mDisabledCameraOnKeyguardSecure;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.device_admin_general);

mGeneralAdmin = (CheckBoxPreference) findPreference("key_enable_admin");
mDisabledAllCamera = (CheckBoxPreference) findPreference("key_disable_all_camera");
mDisabledKeyguardWidget = (CheckBoxPreference) findPreference("key_disable_keyguard_widgets");
mDisabledCameraOnKeyguardSecure = (CheckBoxPreference) findPreference("key_disable_keyguard_secure_camera");

mGeneralAdmin.setOnPreferenceChangeListener(this);
mDisabledAllCamera.setOnPreferenceChangeListener(this);
mDisabledKeyguardWidget.setOnPreferenceChangeListener(this);
mDisabledCameraOnKeyguardSecure.setOnPreferenceChangeListener(this);
}

/*
* 根据Fragment的生命周期,当我们从激活界面返回到Fragment主界面时,会重新调用此方法,
* 我们在此方法中根据设备管理器的激活状态来决定复选框的状态
*/
@Override
public void onResume() {
super.onResume();
mActiveAdmin = isActiveAdmin();
mGeneralAdmin.setChecked(mActiveAdmin);
// 更新capabilities区域的状态
enableCapabilitiesArea(mActiveAdmin);
// System.out.println("mActiveAdmin on resume:" + mActiveAdmin);
if (mActiveAdmin) {
mDPM.setCameraDisabled(mDeviceAdmin,
mDisabledAllCamera.isChecked());
if (mDisabledKeyguardWidget.isChecked()) {
setKeyGuardDisabled(KEYGUARD_DISABLE_WIDGET);
} else {
setKeyGuardDisabled(KEYGUARD_ENABLE_WIDGET);
}
if (mDisabledCameraOnKeyguardSecure.isChecked()) {
setKeyGuardDisabled(KEYGUARD_DISABLE_SECURE_CAMERA);
} else {
setKeyGuardDisabled(KEYGUARD_ENABLE_SECURE_CAMERA);
}
reloadSumary();
}

}

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
mActiveAdmin = isActiveAdmin();
// System.out.println("mActiveAdmin:" + mActiveAdmin);
// System.out.println("value:" + value);
if (preference == mGeneralAdmin) {
if (value != mActiveAdmin) {
// 当复选框为选中状态时
if (value) {
Intent intent = new Intent(
DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
mDeviceAdmin);
// 在激活设备管理器界面添加说明文字
intent.putExtra(
DevicePolicyManager.EXTRA_ADD_EXPLANATION,
"在这里可以添加自定义的说明性内容");
startActivityForResult(intent,
REQUEST_CODE_ADMIN_ENABLE);
// 返回false不更新复选框的状态直到我们真正激活设备管理器
return false;
} else {
mDPM.removeActiveAdmin(mDeviceAdmin);
mActiveAdmin = false;
enableCapabilitiesArea(false);
resetCapabilitiesArea(false);
}
}
} else if (preference == mDisabledAllCamera) {
mDPM.setCameraDisabled(mDeviceAdmin, value);
// 没返回true之前复选框的状态不会改变
// System.out.println("mDisabledAllCamera:"+mDisabledAllCamera.isChecked());
reloadSumary();
} else if (preference == mDisabledKeyguardWidget) {
int flags = 0;
if (value) {
setKeyGuardDisabled(KEYGUARD_DISABLE_WIDGET);
} else {
setKeyGuardDisabled(KEYGUARD_ENABLE_WIDGET);
}

} else if (preference == mDisabledCameraOnKeyguardSecure) {
if (value) {
setKeyGuardDisabled(KEYGUARD_DISABLE_SECURE_CAMERA);
} else {
setKeyGuardDisabled(KEYGUARD_ENABLE_SECURE_CAMERA);
}
}
/*
* else if(preference==mDisabledKeyguardWidget||preference==
* mDisabledCameraOnKeyguardSecure){
* //在返回true之前复选框的状态不会改变,所以demo的代码是有问题的,此时即使我们勾选了复选框,在这里我们取到的值
* //仍然是false因为还没改变,那么我们得到的flag也当然是0,我们在此时调用reloadSumary(),是在flag为0的
* //情况下得到的运算结果,所以即使我们勾选了复选框,但摘要信息却没有发生变化。
* //System.out.println("mDisabledKeyguardWidget:"
* +mDisabledKeyguardWidget.isChecked());
* //System.out.println("flag:"+createKeyGuardDisableFlag());
* mDPM.setKeyguardDisabledFeatures(mDeviceAdmin,
* createKeyGuardDisableFlag()); reloadSumary(); }
*/
return true;
}

private void resetCapabilitiesArea(boolean enable) {
mDisabledAllCamera.setChecked(enable);
mDisabledKeyguardWidget.setChecked(enable);
mDisabledCameraOnKeyguardSecure.setChecked(enable);

}

private void setKeyGuardDisabled(int feature) {

switch (feature) {
case KEYGUARD_DISABLE_WIDGET:
flag |= DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL;
break;
case KEYGUARD_DISABLE_SECURE_CAMERA:
flag |= DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA;
break;
case KEYGUARD_ENABLE_WIDGET:
flag &= (~DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL);
break;
case KEYGUARD_ENABLE_SECURE_CAMERA:
flag &= (~DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA);
break;
default:
break;
}
mDPM.setKeyguardDisabledFeatures(mDeviceAdmin, flag);
reloadSumary();

/*
* int flag=DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
* //System
* .out.println("mDisabledKeyguardWidget:"+mDisabledKeyguardWidget
* .isChecked()); flag|=mDisabledKeyguardWidget.isChecked() ?
* DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL:0;
* //System.out.println("flag in create:"+flag);
* flag|=mDisabledCameraOnKeyguardSecure.isChecked() ?
* DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA:0; return
* flag;
*/
}

private void reloadSumary() {
String cameraSummary = mDPM.getCameraDisabled(mDeviceAdmin) ? "camera disabled"
: "camera enabled";
mDisabledAllCamera.setSummary(cameraSummary);

int disabled = mDPM.getKeyguardDisabledFeatures(mDeviceAdmin);
// System.out.println("disabled:" + disabled);

String keyguardWidgetSummary = (disabled & DevicePolicyManager.KEYGUARD_DISABLE_WIDGETS_ALL) != 0 ? "keyguard widgets disabled"
: "keyguard widgets enabled";
mDisabledKeyguardWidget.setSummary(keyguardWidgetSummary);

String keyguardSecureCameraSummary = (disabled & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0 ? "keyguard secure camera disabled"
: "keyguard secure camera enabled";
mDisabledCameraOnKeyguardSecure
.setSummary(keyguardSecureCameraSummary);
}

/*
* 设置capabilicities区域是否可以被设置
*/
private void enableCapabilitiesArea(boolean enabled) {
mDisabledAllCamera.setEnabled(enabled);
mDisabledKeyguardWidget.setEnabled(enabled);
mDisabledCameraOnKeyguardSecure.setEnabled(enabled);
}
}

/*
* 定义一个广播接收者,该类继承DeviceAdminReceiver,当系统设备管理器执行了某一的设置后,
* 用于调用相应的方法,处理设置被执行后要执行的内容
*/
public static class MyAdminReceiver extends DeviceAdminReceiver {
private void showToast(Context context, String msg) {
// 定义R.string.device_admin_status为一个带参数的字符串
String status = context
.getString(R.string.device_admin_status, msg);
Toast.makeText(context, status, 0).show();
}

@Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Enable");
}

@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
String disableWarning = "This is an option message to warn the user about disabling";
return disableWarning;
}

@Override
public void onDisabled(Context context, Intent intent) {
showToast(context, "Disable");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: