天天看點

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,如需轉載請自行聯系原作者

繼續閱讀