天天看点

Android屏幕锁定详解完整版(二)

    最近有朋友问屏幕锁定的问题,小马自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,下个小决心,自己照着官方文档学习下,现在做好了,小马废话不多说,先发下截图,看下效果,需要注意的地方小马会加注释,有问题的朋友可以直接留言,我们共同学习交流,共同提高进步!直接看效果图:

 一:未设置密码时进入系统设置的效果图如下:

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102539160.jpg"></a>

 二:运行DEMO,进入应用时:

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102610404.jpg"></a>

 三:设置密码方式预览:

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102646279.jpg"></a>

 四:只设置密码保护时的效果图

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102710309.jpg"></a>

 五:密码解密效果图

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102732804.jpg"></a>

 六:设置九宫格加密时的效果图

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102753652.jpg"></a>

 七:九宫格解密时的效果图

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102811673.jpg"></a>

 八:解密成功后,进入我们手机系统的图

<a target="_blank" href="http://blog.51cto.com/attachment/201202/102837100.jpg"></a>

     下面来简单的看下源码吧,此处讲下,这个小DEMO也是小马临时学习下的,有讲的不明白的地方请朋友直接批评指出,有错肯定改的,吼吼..看代码:

 主控制类:

package com.xiaoma.policymanager.demo; 

import android.app.Activity; 

import android.app.admin.DevicePolicyManager; 

import android.content.Intent; 

import android.content.SharedPreferences; 

import android.os.Bundle; 

import android.view.View; 

import android.widget.AdapterView; 

import android.widget.ArrayAdapter; 

import android.widget.Button; 

import android.widget.EditText; 

import android.widget.LinearLayout; 

import android.widget.Spinner; 

import android.widget.TextView; 

/**   

* @Title: PolicySetupActivity.java 

* @Package com.xiaoma.policymanager.demo 

* @Description: 屏幕锁实现测试  

* @author MZH 

*/ 

public class PolicySetupActivity extends Activity { 

    private static final int REQ_ACTIVATE_DEVICE_ADMIN = 10; 

    private static final String SCREEN_ID_KEY = "LAYOUT_ID"; 

    /**存储配置信息的SP文件名*/ 

    private static final String APP_PREF = "APP_PREF"; 

    /**有未知屏幕ID时返回此标识*/ 

    private static final int UNKNOWN_SCREEN_ID = -1; 

    /**声明组件*/ 

    private Spinner mPasswordQualityInputField; 

    private EditText mPasswordLengthInputField; 

    private EditText mPasswordMinUppercaseInputField; 

    /**获取配置操作类对象*/ 

    private Policy mPolicy; 

    /**当前屏幕ID*/ 

    private int mCurrentScreenId; 

    @Override 

    public void onCreate(Bundle savedInstanceState) { 

        super.onCreate(savedInstanceState); 

        mPolicy = new Policy(this); 

    } 

    protected void onResume() { 

        super.onResume(); 

        /**获取本地SP文件中屏幕锁的配置信息*/ 

        SharedPreferences prefs = getSharedPreferences(APP_PREF, MODE_PRIVATE); 

        final int savedScreenId = prefs.getInt(SCREEN_ID_KEY, UNKNOWN_SCREEN_ID); 

        /**如果获取到的ID为空,则跳转到设置页*/ 

        if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) { 

            setScreenContent(R.layout.activity_policy_setup); 

        /**跳转到配置详情页*/ 

        } else { 

            setScreenContent(savedScreenId); 

        } 

    /** 

     * 设置屏幕方法实现,详细的可以自己看下,小马也是边参照官方文档,边学习的 

     * 有好想法..有问题的朋友们可以留言.我们一起学习 

     * @param screenId 

     */ 

    private void setScreenContent(final int screenId) { 

        /**记录当前屏幕ID,并预先存入本地SP配置文件中*/ 

        mCurrentScreenId = screenId; 

        setContentView(mCurrentScreenId); 

        getSharedPreferences(APP_PREF, MODE_PRIVATE).edit().putInt( 

                SCREEN_ID_KEY, mCurrentScreenId).commit(); 

        switch (mCurrentScreenId) { 

        case R.layout.activity_policy_setup: 

            initPolicySetupScreen(); 

            initNavigation(); 

            break; 

        case R.layout.activity_view_policy: 

            initViewPolicyScreen(); 

     * 关闭页面时将当前配置写入本地SP文件中 

    protected void onPause() { 

        super.onPause(); 

        if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy(); 

    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 

        if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN &amp;&amp; resultCode == RESULT_OK) { 

            // User just activated the application as a device administrator. 

            setScreenContent(mCurrentScreenId); 

            super.onActivityResult(requestCode, resultCode, data); 

     * 重载返回键方法,如果已当前屏幕为已设置密码页,则展示详情 

    public void onBackPressed() { 

        if (mCurrentScreenId == R.layout.activity_view_policy) { 

            return; 

        super.onBackPressed(); 

     * 初始化化设置页 

    private void initPolicySetupScreen() { 

        mPasswordQualityInputField = (Spinner) findViewById(R.id.policy_password_quality); 

        mPasswordLengthInputField = (EditText) findViewById(R.id.policy_password_length); 

        mPasswordMinUppercaseInputField = (EditText) findViewById(R.id.policy_password_uppercase); 

        ArrayAdapter&lt;CharSequence&gt; adapter = ArrayAdapter.createFromResource(this, 

                R.array.password_types, android.R.layout.simple_spinner_item); 

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 

        mPasswordQualityInputField.setAdapter(adapter); 

        mPasswordQualityInputField.setOnItemSelectedListener( 

                new AdapterView.OnItemSelectedListener() { 

            public void onItemSelected(AdapterView&lt;?&gt; parent, View view, int pos, long id) { 

                LinearLayout passwordMinUppercaseView = 

                        (LinearLayout) findViewById(R.id.password_uppercase_view); 

                // The minimum number of upper case field is only applicable for password 

                // qualities: alpha, alphanumeric, or complex. 

                if (pos &gt; 2) 

                    passwordMinUppercaseView.setVisibility(View.VISIBLE); 

                else 

                    passwordMinUppercaseView.setVisibility(View.GONE); 

            } 

            public void onNothingSelected(AdapterView&lt;?&gt; parent) {} 

        }); 

        /**阅读先前配置的相关信息*/ 

        mPolicy.readFromLocal(); 

        mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality()); 

        if (mPolicy.getPasswordLength() &gt; 0) { 

            mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength())); 

            mPasswordLengthInputField.setText(""); 

        if (mPolicy.getPasswordMinUpperCase() &gt; 0) { 

            mPasswordMinUppercaseInputField.setText( 

                    String.valueOf(mPolicy.getPasswordMinUpperCase())); 

            mPasswordMinUppercaseInputField.setText(""); 

     * 初始化查看详情页 

    private void initViewPolicyScreen() { 

        TextView passwordQualityView = (TextView) findViewById(R.id.policy_password_quality); 

        TextView passwordLengthView = (TextView) findViewById(R.id.policy_password_length); 

        // Read previously saved policy and populate on the UI. 

        int passwordQualitySelection = mPolicy.getPasswordQuality(); 

        passwordQualityView.setText( 

                getResources().getStringArray(R.array.password_types)[passwordQualitySelection]); 

        passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength())); 

        if (passwordQualitySelection &gt; 2) { 

            LinearLayout passwordMinUppercaseView = 

                    (LinearLayout) findViewById(R.id.password_uppercase_view); 

            passwordMinUppercaseView.setVisibility(View.VISIBLE); 

            ((TextView) findViewById(R.id.policy_password_uppercase)).setText( 

     * 设置导航信息 

    private void initNavigation() { 

        if (!mPolicy.isAdminActive()) { 

            // Activates device administrator. 

            setupNavigation(R.string.setup_message_activate, 

                    R.string.setup_action_activate, 

                    mActivateButtonListener); 

        } else if (mCurrentScreenId == R.layout.activity_policy_setup) { 

            setupNavigation(R.string.setup_message_set_policy, 

                    R.string.setup_action_set_policy, 

                    new View.OnClickListener() { 

                        public void onClick(View view) { 

                            writePolicy(); 

                            mPolicy.configurePolicy(); 

                            setScreenContent(R.layout.activity_view_policy); 

                        } 

                    }); 

        else if (!mPolicy.isActivePasswordSufficient()) { 

            // Launches password set-up screen in Settings. 

            setupNavigation(R.string.setup_message_enforce_policy, 

                    R.string.setup_action_enforce_policy, 

                    mEnforcePolicyListener); 

            // Grants access to secure content. 

            setupNavigation(R.string.setup_message_go_secured, 

                    R.string.setup_action_go_secured, 

                            startActivity(new Intent(view.getContext(), SecureActivity.class)); 

     * 监听器实现,这个小马不多讲了. 

    private View.OnClickListener mActivateButtonListener = new View.OnClickListener() { 

        @Override 

        public void onClick(View v) { 

            // First, persist the policy.  Then, launch intent to trigger the system screen 

            // requesting user to confirm the activation of the device administrator. 

            writePolicy(); 

            Intent activateDeviceAdminIntent = 

                new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 

            activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 

                    mPolicy.getPolicyAdmin()); 

            // It is good practice to include the optional explanation text to explain to 

            // user why the application is requesting to be a device administrator.  The system 

            // will display this message on the activation screen. 

            activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, 

                    getResources().getString(R.string.device_admin_activation_message)); 

            startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN); 

    }; 

     * 监听器实现,这个小马也不多讲了. 

    private View.OnClickListener mEnforcePolicyListener = new View.OnClickListener() { 

            // The device administration API does not "fix" the password if it is 

            // determined that the current password does not conform to what is requested 

            // by the policy.  The caller is responsible for triggering the password set up 

            // screen via the below intent. 

            Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); 

            startActivity(intent); 

     * 设置激活按钮不同状态时的文本信息 

     * @param messageResId 

     * @param buttonTextResId 

     * @param listener 

    private void setupNavigation(int messageResId, int buttonTextResId, 

            View.OnClickListener listener) { 

        TextView setupMessage = (TextView) findViewById(R.id.setup_message); 

        setupMessage.setText(messageResId); 

        Button actionBtn = (Button) findViewById(R.id.setup_action_btn); 

        actionBtn.setText(buttonTextResId); 

        actionBtn.setOnClickListener(listener); 

    // 在关闭此页时,将配置信息写入本地SP文件中. 

    private void writePolicy() { 

        int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId(); 

        int passwordLength = 0; 

        try { 

            passwordLength = Integer.valueOf(mPasswordLengthInputField.getText().toString()); 

        } catch (NumberFormatException nfe) {}  // Defaults to 0. 

        int passwordMinUppercase = 0; 

            passwordMinUppercase = 

                    Integer.valueOf(mPasswordMinUppercaseInputField.getText().toString()); 

        mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase); 

 配置操作类:

import android.app.admin.DeviceAdminReceiver; 

import android.content.ComponentName; 

import android.content.Context; 

import android.os.Build; 

* @Title: Policy.java 

* @Description: 用来获取相关安全配置信息的类 

public class Policy { 

    public static final int REQUEST_ADD_DEVICE_ADMIN = 1; 

    /**保存屏幕锁相关参数的SP文件名*/ 

    /**下面三个是往SP中存储时的Key*/ 

    private static final String KEY_PASSWORD_LENGTH = "PW_LENGTH"; 

    private static final String KEY_PASSWORD_QUALITY = "PW_QUALITY"; 

    private static final String KEY_PASSWORD_MIN_UPPERCASE = "PW_MIN_UPPERCASE"; 

     * 下面是可允许输入密码的类型,此处的类型必须与string.xml文件中定义的arrays.xml中的相匹配 

    final static int[] PASSWORD_QUALITY_VALUES = new int[] { 

        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 

        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 

        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, 

        DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, 

        DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, 

        DevicePolicyManager.PASSWORD_QUALITY_COMPLEX 

    private int mPasswordQuality; 

    private int mPasswordLength; 

    private int mPasswordMinUpperCase; 

    private Context mContext; 

    private DevicePolicyManager mDPM; 

    private ComponentName mPolicyAdmin; 

     * 构造器,在new此类对象时,获取系统级管理员对象 DevicePolicyManager 

     * @param context 

    public Policy(Context context) { 

        mContext = context; 

        mPasswordQuality = -1; 

        mPasswordLength = 0; 

        mPasswordMinUpperCase = 0; 

        mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); 

        mPolicyAdmin = new ComponentName(context, PolicyAdmin.class); 

     * 保存设备参数 

    public void saveToLocal(int passwordQuality, int passwordLength, int passwordMinUppercase) { 

        SharedPreferences.Editor editor = 

                mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE).edit(); 

        if (mPasswordQuality != passwordQuality) { 

            editor.putInt(KEY_PASSWORD_QUALITY, passwordQuality); 

            mPasswordQuality = passwordQuality; 

        if (mPasswordLength != passwordLength) { 

            editor.putInt(KEY_PASSWORD_LENGTH, passwordLength); 

            mPasswordLength = passwordLength; 

        if (mPasswordMinUpperCase != passwordMinUppercase) { 

            editor.putInt(KEY_PASSWORD_MIN_UPPERCASE, passwordMinUppercase); 

            mPasswordMinUpperCase = passwordMinUppercase; 

        editor.commit(); 

     * 从本地SP文件中获取密码配置参数 

    public void readFromLocal() { 

        SharedPreferences prefs = mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE); 

        mPasswordQuality = prefs.getInt(KEY_PASSWORD_QUALITY, -1); 

        mPasswordLength = prefs.getInt(KEY_PASSWORD_LENGTH, -1); 

        mPasswordMinUpperCase = prefs.getInt(KEY_PASSWORD_MIN_UPPERCASE, -1); 

     * 获取密码. 

     * 

     * @return 

    public int getPasswordQuality() { return mPasswordQuality; } 

     * 获取密码长度. 

    public int getPasswordLength() { return mPasswordLength; } 

     * 获取字母密码. 

    public int getPasswordMinUpperCase() { return mPasswordMinUpperCase; } 

     * 获取设备管理的 ComponentName 对象. 

    public ComponentName getPolicyAdmin() { return mPolicyAdmin; } 

     * 判断设备是否被激活. 

    public boolean isAdminActive() { 

        return mDPM.isAdminActive(mPolicyAdmin); 

    public boolean isActivePasswordSufficient() { 

        return mDPM.isActivePasswordSufficient(); 

     * 判断设备是否加安全  

    public boolean isDeviceSecured() { 

        return isAdminActive() &amp;&amp; isActivePasswordSufficient(); 

     * 在声明的mDPM对象中进行配置. 

    public void configurePolicy() { 

        mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]); 

        mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength); 

        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.HONEYCOMB) { 

            mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase); 

     * 下面这个类用来监听各种不同类型的设备管理事件,比如:改变密码..错误密码等等 

    public static class PolicyAdmin extends DeviceAdminReceiver { 

        public void onDisabled(Context context, Intent intent) { 

            // Called when the app is about to be deactivated as a device administrator. 

            super.onDisabled(context, intent); 

            SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE); 

            /**清除以前在SP文件下保存的所有值*/ 

            prefs.edit().clear().commit(); 

 权限验证类:

* @Title: SecureActivity.java 

* @Description: 权限验证类实现 

public class SecureActivity extends Activity { 

        // Check to see if the device is properly secured as per the policy.  Send user 

        // back to policy set up screen if necessary. 

        Policy policy = new Policy(this); 

        policy.readFromLocal(); 

        if (!policy.isDeviceSecured()) { 

            Intent intent = new Intent(); 

            intent.setClass(this, PolicySetupActivity.class); 

            intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | 

                            Intent.FLAG_ACTIVITY_CLEAR_TASK); 

            finish(); 

        setContentView(R.layout.activity_secure); 

    吼吼,效果就这样完成了,源码小马也放到附件里面了,如果有需要的朋友可以自行下载下的,有问题可直接留言,我们一起学习,一起进步,如有小马讲不好的地方,请朋友直接批评指点..小马定感谢...谢谢..加油加油!

<a href="http://down.51cto.com/data/2359941" target="_blank">附件:http://down.51cto.com/data/2359941</a>

     本文转自华华世界 51CTO博客,原文链接:http://blog.51cto.com/mzh3344258/791505,如需转载请自行联系原作者

继续阅读