最近在一個視頻項目中遇到了很多屏幕鎖定的問題,自己也在學習,網上找了下也沒太詳細的例子,看的資料書上也沒有有關屏幕鎖定程序的介紹,從之前寫的文章中抽過來放研究院中,希望能幫助更多想了解或學習屏幕鎖的朋友們學習研究,自己照著官方文檔學習下,現在做好了,廢話不多說,先發下截圖,看下效果,需要注意的地方會加注釋,有問題的朋友可以直接留言,我們共同學習交流,共同提高進步!直接看效果圖:
一:未設置密碼時進入系統設置的效果圖如下:
二:運行DEMO,進入應用時:
三:設置密碼方式預覽:
四:只設置密碼保護時的效果圖
五:密碼解密效果圖
六:設置九宮格加密時的效果圖
七:九宮格解密時的效果圖
八:解密成功後,進入我們手機系統的圖
下面來簡單的看下源碼吧,此處講下,這個小DEMO也是臨時學習下的,有講的不明白的地方請朋友直接批評指出,有錯肯定改的,吼吼..看代碼:
主控制類:
Java代碼
- package com.xiaoma.policymanager.demo;
-
- import android.app.Activity;
- import android.app.admin.DevicePolicyManager;
- import android.content.Intent;
- mport 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;
- mport 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);
- }
-
- @Override
- 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();
- initNavigation();
- break;
- }
- }
-
- /**
- * 關閉頁面時將當前配置寫入本地SP文件中
- */
- @Override
- protected void onPause() {
- super.onPause();
- if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy();
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN && resultCode == RESULT_OK) {
- // User just activated the application as a device administrator.
- setScreenContent(mCurrentScreenId);
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-
- /**
- * 重載返回鍵方法,如果已當前屏幕為已設置密碼頁,則展示詳情
- */
- @Override
- public void onBackPressed() {
- if (mCurrentScreenId == R.layout.activity_view_policy) {
- setScreenContent(R.layout.activity_policy_setup);
- 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<CharSequence> 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<?> 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 > 2)
- passwordMinUppercaseView.setVisibility(View.VISIBLE);
- else
- passwordMinUppercaseView.setVisibility(View.GONE);
- }
-
- public void onNothingSelected(AdapterView<?> parent) {}
- });
-
- /**閱讀先前配置的相關信息*/
- mPolicy.readFromLocal();
- mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality());
- if (mPolicy.getPasswordLength() > 0) {
- mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength()));
- } else {
- mPasswordLengthInputField.setText("");
- }
-
- if (mPolicy.getPasswordMinUpperCase() > 0) {
- mPasswordMinUppercaseInputField.setText(
- String.valueOf(mPolicy.getPasswordMinUpperCase()));
- } else {
- 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.
- mPolicy.readFromLocal();
- int passwordQualitySelection = mPolicy.getPasswordQuality();
- passwordQualityView.setText(
- getResources().getStringArray(R.array.password_types)[passwordQualitySelection]);
- passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength()));
- if (passwordQualitySelection > 2) {
- LinearLayout passwordMinUppercaseView =
- (LinearLayout) findViewById(R.id.password_uppercase_view);
- passwordMinUppercaseView.setVisibility(View.VISIBLE);
- ((TextView) findViewById(R.id.policy_password_uppercase)).setText(
- String.valueOf(mPolicy.getPasswordMinUpperCase()));
- }
- }
-
- /**
- * 設置導航信息
- */
- 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);
- } else {
- // Grants access to secure content.
- setupNavigation(R.string.setup_message_go_secured,
- R.string.setup_action_go_secured,
- new View.OnClickListener() {
- public void onClick(View view) {
- 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() {
- @Override
- public void onClick(View v) {
- writePolicy();
- // 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;
- try {
- passwordMinUppercase =
- Integer.valueOf(mPasswordMinUppercaseInputField.getText().toString());
- } catch (NumberFormatException nfe) {} // Defaults to 0.
-
- mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase);
- }
- }
配置操作類:
Java代碼
- package com.xiaoma.policymanager.demo;
-
- import android.app.Activity;
- import android.app.admin.DeviceAdminReceiver;
- import android.app.admin.DevicePolicyManager;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.SharedPreferences;
- import android.os.Build;
-
- /**
- * @Title: Policy.java
- * @Package com.xiaoma.policymanager.demo
- * @Description: 用來獲取相關安全配置信息的類
- * @author MZH
- */
- public class Policy {
- public static final int REQUEST_ADD_DEVICE_ADMIN = 1;
-
- /**保存屏幕鎖相關參數的SP文件名*/
- private static final String APP_PREF = "APP_PREF";
- /**下面三個是往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; }
-
- /**
- * 獲取密碼長度.
- *
- * @return
- */
- public int getPasswordLength() { return mPasswordLength; }
-
- /**
- * 獲取字母密碼.
- *
- * @return
- */
- public int getPasswordMinUpperCase() { return mPasswordMinUpperCase; }
-
- /**
- * 獲取設備管理的 ComponentName 對象.
- *
- * @return
- */
- public ComponentName getPolicyAdmin() { return mPolicyAdmin; }
-
- /**
- * 判斷設備是否被激活.
- *
- * @return
- */
- public boolean isAdminActive() {
- return mDPM.isAdminActive(mPolicyAdmin);
- }
-
- public boolean isActivePasswordSufficient() {
- return mDPM.isActivePasswordSufficient();
- }
-
- /**
- * 判斷設備是否加安全
- * @return
- */
- public boolean isDeviceSecured() {
- return isAdminActive() && isActivePasswordSufficient();
- }
-
- /**
- * 在聲明的mDPM對象中進行配置.
- */
- public void configurePolicy() {
- mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]);
- mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase);
- }
- }
-
- /**
- * 下面這個類用來監聽各種不同類型的設備管理事件,比如:改變密碼..錯誤密碼等等
- */
- public static class PolicyAdmin extends DeviceAdminReceiver {
-
- @Override
- 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();
- }
- }
- }
權限驗證類:
Java代碼
- package com.xiaoma.policymanager.demo;
-
- import android.app.Activity;
- import android.content.Intent;
-
- /**
- * @Title: SecureActivity.java
- * @Package com.xiaoma.policymanager.demo
- * @Description: 權限驗證類實現
- * @author MZH
- */
- public class SecureActivity extends Activity {
-
- @Override
- protected void onResume() {
- super.onResume();
- // 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);
- startActivity(intent);
- finish();
- }
- setContentView(R.layout.activity_secure);
- }
- }