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

这个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");
        }

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值