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

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

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

 

 三:设置密码方式预览:

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

 五:密码解密效果图

 

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

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

 

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

 

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

 主控制类:

  1. package com.xiaoma.policymanager.demo; 
  2.  
  3. import android.app.Activity; 
  4. import android.app.admin.DevicePolicyManager; 
  5. import android.content.Intent; 
  6. import android.content.SharedPreferences; 
  7. import android.os.Bundle; 
  8. import android.view.View; 
  9. import android.widget.AdapterView; 
  10. import android.widget.ArrayAdapter; 
  11. import android.widget.Button; 
  12. import android.widget.EditText; 
  13. import android.widget.LinearLayout; 
  14. import android.widget.Spinner; 
  15. import android.widget.TextView; 
  16.  
  17. /**   
  18. * @Title: PolicySetupActivity.java 
  19. * @Package com.xiaoma.policymanager.demo 
  20. * @Description: 屏幕锁实现测试  
  21. * @author MZH 
  22. */ 
  23. public class PolicySetupActivity extends Activity { 
  24.     private static final int REQ_ACTIVATE_DEVICE_ADMIN = 10
  25.     private static final String SCREEN_ID_KEY = "LAYOUT_ID"
  26.      
  27.     /**存储配置信息的SP文件名*/ 
  28.     private static final String APP_PREF = "APP_PREF"
  29.     /**有未知屏幕ID时返回此标识*/ 
  30.     private static final int UNKNOWN_SCREEN_ID = -1
  31.  
  32.     /**声明组件*/ 
  33.     private Spinner mPasswordQualityInputField; 
  34.     private EditText mPasswordLengthInputField; 
  35.     private EditText mPasswordMinUppercaseInputField; 
  36.      
  37.     /**获取配置操作类对象*/ 
  38.     private Policy mPolicy; 
  39.     /**当前屏幕ID*/ 
  40.     private int mCurrentScreenId; 
  41.  
  42.     @Override 
  43.     public void onCreate(Bundle savedInstanceState) { 
  44.         super.onCreate(savedInstanceState); 
  45.         mPolicy = new Policy(this); 
  46.     } 
  47.  
  48.     @Override 
  49.     protected void onResume() { 
  50.         super.onResume(); 
  51.         /**获取本地SP文件中屏幕锁的配置信息*/ 
  52.         SharedPreferences prefs = getSharedPreferences(APP_PREF, MODE_PRIVATE); 
  53.         final int savedScreenId = prefs.getInt(SCREEN_ID_KEY, UNKNOWN_SCREEN_ID); 
  54.         /**如果获取到的ID为空,则跳转到设置页*/ 
  55.         if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) { 
  56.             setScreenContent(R.layout.activity_policy_setup); 
  57.         /**跳转到配置详情页*/ 
  58.         } else { 
  59.             setScreenContent(savedScreenId); 
  60.         } 
  61.     } 
  62.      
  63.     /** 
  64.      * 设置屏幕方法实现,详细的可以自己看下,小马也是边参照官方文档,边学习的 
  65.      * 有好想法..有问题的朋友们可以留言.我们一起学习 
  66.      * @param screenId 
  67.      */ 
  68.     private void setScreenContent(final int screenId) { 
  69.         /**记录当前屏幕ID,并预先存入本地SP配置文件中*/ 
  70.         mCurrentScreenId = screenId; 
  71.         setContentView(mCurrentScreenId); 
  72.         getSharedPreferences(APP_PREF, MODE_PRIVATE).edit().putInt( 
  73.                 SCREEN_ID_KEY, mCurrentScreenId).commit(); 
  74.         switch (mCurrentScreenId) { 
  75.         case R.layout.activity_policy_setup: 
  76.             initPolicySetupScreen(); 
  77.             initNavigation(); 
  78.             break
  79.         case R.layout.activity_view_policy: 
  80.             initViewPolicyScreen(); 
  81.             initNavigation(); 
  82.             break
  83.         } 
  84.     } 
  85.  
  86.     /** 
  87.      * 关闭页面时将当前配置写入本地SP文件中 
  88.      */ 
  89.     @Override 
  90.     protected void onPause() { 
  91.         super.onPause(); 
  92.         if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy(); 
  93.     } 
  94.  
  95.     @Override 
  96.     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
  97.         if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN && resultCode == RESULT_OK) { 
  98.             // User just activated the application as a device administrator. 
  99.             setScreenContent(mCurrentScreenId); 
  100.         } else { 
  101.             super.onActivityResult(requestCode, resultCode, data); 
  102.         } 
  103.     } 
  104.  
  105.     /** 
  106.      * 重载返回键方法,如果已当前屏幕为已设置密码页,则展示详情 
  107.      */ 
  108.     @Override 
  109.     public void onBackPressed() { 
  110.         if (mCurrentScreenId == R.layout.activity_view_policy) { 
  111.             setScreenContent(R.layout.activity_policy_setup); 
  112.             return
  113.         } 
  114.         super.onBackPressed(); 
  115.     } 
  116.  
  117.     /** 
  118.      * 初始化化设置页 
  119.      */ 
  120.     private void initPolicySetupScreen() { 
  121.         mPasswordQualityInputField = (Spinner) findViewById(R.id.policy_password_quality); 
  122.         mPasswordLengthInputField = (EditText) findViewById(R.id.policy_password_length); 
  123.         mPasswordMinUppercaseInputField = (EditText) findViewById(R.id.policy_password_uppercase); 
  124.         ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this
  125.                 R.array.password_types, android.R.layout.simple_spinner_item); 
  126.         adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
  127.         mPasswordQualityInputField.setAdapter(adapter); 
  128.         mPasswordQualityInputField.setOnItemSelectedListener( 
  129.                 new AdapterView.OnItemSelectedListener() { 
  130.             public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { 
  131.                 LinearLayout passwordMinUppercaseView = 
  132.                         (LinearLayout) findViewById(R.id.password_uppercase_view); 
  133.                 // The minimum number of upper case field is only applicable for password 
  134.                 // qualities: alpha, alphanumeric, or complex. 
  135.                 if (pos > 2
  136.                     passwordMinUppercaseView.setVisibility(View.VISIBLE); 
  137.                 else 
  138.                     passwordMinUppercaseView.setVisibility(View.GONE); 
  139.             } 
  140.  
  141.             public void onNothingSelected(AdapterView<?> parent) {} 
  142.         }); 
  143.  
  144.         /**阅读先前配置的相关信息*/ 
  145.         mPolicy.readFromLocal(); 
  146.         mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality()); 
  147.         if (mPolicy.getPasswordLength() > 0) { 
  148.             mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength())); 
  149.         } else { 
  150.             mPasswordLengthInputField.setText(""); 
  151.         } 
  152.  
  153.         if (mPolicy.getPasswordMinUpperCase() > 0) { 
  154.             mPasswordMinUppercaseInputField.setText( 
  155.                     String.valueOf(mPolicy.getPasswordMinUpperCase())); 
  156.         } else { 
  157.             mPasswordMinUppercaseInputField.setText(""); 
  158.         } 
  159.     } 
  160.  
  161.     /** 
  162.      * 初始化查看详情页 
  163.      */ 
  164.     private void initViewPolicyScreen() { 
  165.         TextView passwordQualityView = (TextView) findViewById(R.id.policy_password_quality); 
  166.         TextView passwordLengthView = (TextView) findViewById(R.id.policy_password_length); 
  167.  
  168.         // Read previously saved policy and populate on the UI. 
  169.         mPolicy.readFromLocal(); 
  170.         int passwordQualitySelection = mPolicy.getPasswordQuality(); 
  171.         passwordQualityView.setText( 
  172.                 getResources().getStringArray(R.array.password_types)[passwordQualitySelection]); 
  173.         passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength())); 
  174.         if (passwordQualitySelection > 2) { 
  175.             LinearLayout passwordMinUppercaseView = 
  176.                     (LinearLayout) findViewById(R.id.password_uppercase_view); 
  177.             passwordMinUppercaseView.setVisibility(View.VISIBLE); 
  178.             ((TextView) findViewById(R.id.policy_password_uppercase)).setText( 
  179.                     String.valueOf(mPolicy.getPasswordMinUpperCase())); 
  180.         } 
  181.     } 
  182.  
  183.     /** 
  184.      * 设置导航信息 
  185.      */ 
  186.     private void initNavigation() { 
  187.         if (!mPolicy.isAdminActive()) { 
  188.             // Activates device administrator. 
  189.             setupNavigation(R.string.setup_message_activate, 
  190.                     R.string.setup_action_activate, 
  191.                     mActivateButtonListener); 
  192.         } else if (mCurrentScreenId == R.layout.activity_policy_setup) { 
  193.             setupNavigation(R.string.setup_message_set_policy, 
  194.                     R.string.setup_action_set_policy, 
  195.                     new View.OnClickListener() { 
  196.                         public void onClick(View view) { 
  197.                             writePolicy(); 
  198.                             mPolicy.configurePolicy(); 
  199.                             setScreenContent(R.layout.activity_view_policy); 
  200.                         } 
  201.                     }); 
  202.         } 
  203.         else if (!mPolicy.isActivePasswordSufficient()) { 
  204.             // Launches password set-up screen in Settings. 
  205.             setupNavigation(R.string.setup_message_enforce_policy, 
  206.                     R.string.setup_action_enforce_policy, 
  207.                     mEnforcePolicyListener); 
  208.         } else { 
  209.             // Grants access to secure content. 
  210.             setupNavigation(R.string.setup_message_go_secured, 
  211.                     R.string.setup_action_go_secured, 
  212.                     new View.OnClickListener() { 
  213.                         public void onClick(View view) { 
  214.                             startActivity(new Intent(view.getContext(), SecureActivity.class)); 
  215.                         } 
  216.                     }); 
  217.         } 
  218.     } 
  219.  
  220.     /** 
  221.      * 监听器实现,这个小马不多讲了. 
  222.      */ 
  223.     private View.OnClickListener mActivateButtonListener = new View.OnClickListener() { 
  224.         @Override 
  225.         public void onClick(View v) { 
  226.             // First, persist the policy.  Then, launch intent to trigger the system screen 
  227.             // requesting user to confirm the activation of the device administrator. 
  228.             writePolicy(); 
  229.             Intent activateDeviceAdminIntent = 
  230.                 new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); 
  231.             activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, 
  232.                     mPolicy.getPolicyAdmin()); 
  233.             // It is good practice to include the optional explanation text to explain to 
  234.             // user why the application is requesting to be a device administrator.  The system 
  235.             // will display this message on the activation screen. 
  236.             activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, 
  237.                     getResources().getString(R.string.device_admin_activation_message)); 
  238.             startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN); 
  239.         } 
  240.     }; 
  241.  
  242.     /** 
  243.      * 监听器实现,这个小马也不多讲了. 
  244.      */ 
  245.     private View.OnClickListener mEnforcePolicyListener = new View.OnClickListener() { 
  246.         @Override 
  247.         public void onClick(View v) { 
  248.             writePolicy(); 
  249.             // The device administration API does not "fix" the password if it is 
  250.             // determined that the current password does not conform to what is requested 
  251.             // by the policy.  The caller is responsible for triggering the password set up 
  252.             // screen via the below intent. 
  253.             Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD); 
  254.             startActivity(intent); 
  255.         } 
  256.     }; 
  257.  
  258.     /** 
  259.      * 设置激活按钮不同状态时的文本信息 
  260.      * @param messageResId 
  261.      * @param buttonTextResId 
  262.      * @param listener 
  263.      */ 
  264.     private void setupNavigation(int messageResId, int buttonTextResId, 
  265.             View.OnClickListener listener) { 
  266.         TextView setupMessage = (TextView) findViewById(R.id.setup_message); 
  267.         setupMessage.setText(messageResId); 
  268.         Button actionBtn = (Button) findViewById(R.id.setup_action_btn); 
  269.         actionBtn.setText(buttonTextResId); 
  270.         actionBtn.setOnClickListener(listener); 
  271.     } 
  272.  
  273.     // 在关闭此页时,将配置信息写入本地SP文件中. 
  274.     private void writePolicy() { 
  275.         int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId(); 
  276.  
  277.         int passwordLength = 0
  278.         try { 
  279.             passwordLength = Integer.valueOf(mPasswordLengthInputField.getText().toString()); 
  280.         } catch (NumberFormatException nfe) {}  // Defaults to 0. 
  281.  
  282.         int passwordMinUppercase = 0
  283.         try { 
  284.             passwordMinUppercase = 
  285.                     Integer.valueOf(mPasswordMinUppercaseInputField.getText().toString()); 
  286.         } catch (NumberFormatException nfe) {}  // Defaults to 0. 
  287.  
  288.         mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase); 
  289.     } 

 配置操作类:

 

  1. package com.xiaoma.policymanager.demo; 
  2.  
  3. import android.app.Activity; 
  4. import android.app.admin.DeviceAdminReceiver; 
  5. import android.app.admin.DevicePolicyManager; 
  6. import android.content.ComponentName; 
  7. import android.content.Context; 
  8. import android.content.Intent; 
  9. import android.content.SharedPreferences; 
  10. import android.os.Build; 
  11.  
  12. /**   
  13. * @Title: Policy.java 
  14. * @Package com.xiaoma.policymanager.demo 
  15. * @Description: 用来获取相关安全配置信息的类 
  16. * @author MZH 
  17. */ 
  18. public class Policy { 
  19.     public static final int REQUEST_ADD_DEVICE_ADMIN = 1
  20.      
  21.     /**保存屏幕锁相关参数的SP文件名*/ 
  22.     private static final String APP_PREF = "APP_PREF"
  23.     /**下面三个是往SP中存储时的Key*/ 
  24.     private static final String KEY_PASSWORD_LENGTH = "PW_LENGTH"
  25.     private static final String KEY_PASSWORD_QUALITY = "PW_QUALITY"
  26.     private static final String KEY_PASSWORD_MIN_UPPERCASE = "PW_MIN_UPPERCASE"
  27.  
  28.     /** 
  29.      * 下面是可允许输入密码的类型,此处的类型必须与string.xml文件中定义的arrays.xml中的相匹配 
  30.      */ 
  31.     final static int[] PASSWORD_QUALITY_VALUES = new int[] { 
  32.         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, 
  33.         DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, 
  34.         DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, 
  35.         DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, 
  36.         DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC, 
  37.         DevicePolicyManager.PASSWORD_QUALITY_COMPLEX 
  38.     }; 
  39.  
  40.     private int mPasswordQuality; 
  41.     private int mPasswordLength; 
  42.     private int mPasswordMinUpperCase; 
  43.     private Context mContext; 
  44.     private DevicePolicyManager mDPM; 
  45.     private ComponentName mPolicyAdmin; 
  46.      
  47.     /** 
  48.      * 构造器,在new此类对象时,获取系统级管理员对象 DevicePolicyManager 
  49.      * @param context 
  50.      */ 
  51.     public Policy(Context context) { 
  52.         mContext = context; 
  53.         mPasswordQuality = -1
  54.         mPasswordLength = 0
  55.         mPasswordMinUpperCase = 0
  56.         mDPM = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE); 
  57.         mPolicyAdmin = new ComponentName(context, PolicyAdmin.class); 
  58.     } 
  59.  
  60.     /** 
  61.      * 保存设备参数 
  62.      */ 
  63.     public void saveToLocal(int passwordQuality, int passwordLength, int passwordMinUppercase) { 
  64.         SharedPreferences.Editor editor = 
  65.                 mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE).edit(); 
  66.         if (mPasswordQuality != passwordQuality) { 
  67.             editor.putInt(KEY_PASSWORD_QUALITY, passwordQuality); 
  68.             mPasswordQuality = passwordQuality; 
  69.         } 
  70.         if (mPasswordLength != passwordLength) { 
  71.             editor.putInt(KEY_PASSWORD_LENGTH, passwordLength); 
  72.             mPasswordLength = passwordLength; 
  73.         } 
  74.         if (mPasswordMinUpperCase != passwordMinUppercase) { 
  75.             editor.putInt(KEY_PASSWORD_MIN_UPPERCASE, passwordMinUppercase); 
  76.             mPasswordMinUpperCase = passwordMinUppercase; 
  77.         } 
  78.         editor.commit(); 
  79.     } 
  80.  
  81.     /** 
  82.      * 从本地SP文件中获取密码配置参数 
  83.      */ 
  84.     public void readFromLocal() { 
  85.         SharedPreferences prefs = mContext.getSharedPreferences(APP_PREF, Context.MODE_PRIVATE); 
  86.         mPasswordQuality = prefs.getInt(KEY_PASSWORD_QUALITY, -1); 
  87.         mPasswordLength = prefs.getInt(KEY_PASSWORD_LENGTH, -1); 
  88.         mPasswordMinUpperCase = prefs.getInt(KEY_PASSWORD_MIN_UPPERCASE, -1); 
  89.     } 
  90.  
  91.     /** 
  92.      * 获取密码. 
  93.      * 
  94.      * @return 
  95.      */ 
  96.     public int getPasswordQuality() { return mPasswordQuality; } 
  97.  
  98.     /** 
  99.      * 获取密码长度. 
  100.      * 
  101.      * @return 
  102.      */ 
  103.     public int getPasswordLength() { return mPasswordLength; } 
  104.  
  105.     /** 
  106.      * 获取字母密码. 
  107.      * 
  108.      * @return 
  109.      */ 
  110.     public int getPasswordMinUpperCase() { return mPasswordMinUpperCase; } 
  111.  
  112.     /** 
  113.      * 获取设备管理的 ComponentName 对象. 
  114.      * 
  115.      * @return 
  116.      */ 
  117.     public ComponentName getPolicyAdmin() { return mPolicyAdmin; } 
  118.  
  119.     /** 
  120.      * 判断设备是否被激活. 
  121.      * 
  122.      * @return 
  123.      */ 
  124.     public boolean isAdminActive() { 
  125.         return mDPM.isAdminActive(mPolicyAdmin); 
  126.     } 
  127.      
  128.     public boolean isActivePasswordSufficient() { 
  129.         return mDPM.isActivePasswordSufficient(); 
  130.     } 
  131.      
  132.     /** 
  133.      * 判断设备是否加安全  
  134.      * @return 
  135.      */ 
  136.     public boolean isDeviceSecured() { 
  137.         return isAdminActive() && isActivePasswordSufficient(); 
  138.     } 
  139.  
  140.     /** 
  141.      * 在声明的mDPM对象中进行配置. 
  142.      */ 
  143.     public void configurePolicy() { 
  144.         mDPM.setPasswordQuality(mPolicyAdmin, PASSWORD_QUALITY_VALUES[mPasswordQuality]); 
  145.         mDPM.setPasswordMinimumLength(mPolicyAdmin, mPasswordLength); 
  146.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
  147.             mDPM.setPasswordMinimumUpperCase(mPolicyAdmin, mPasswordMinUpperCase); 
  148.         } 
  149.     } 
  150.  
  151.     /** 
  152.      * 下面这个类用来监听各种不同类型的设备管理事件,比如:改变密码..错误密码等等 
  153.      */ 
  154.     public static class PolicyAdmin extends DeviceAdminReceiver { 
  155.  
  156.         @Override 
  157.         public void onDisabled(Context context, Intent intent) { 
  158.             // Called when the app is about to be deactivated as a device administrator. 
  159.             super.onDisabled(context, intent); 
  160.             SharedPreferences prefs = context.getSharedPreferences(APP_PREF, Activity.MODE_PRIVATE); 
  161.             /**清除以前在SP文件下保存的所有值*/ 
  162.             prefs.edit().clear().commit(); 
  163.         } 
  164.     } 

 权限验证类:

 

  1. package com.xiaoma.policymanager.demo; 
  2.  
  3. import android.app.Activity; 
  4. import android.content.Intent; 
  5.  
  6.  
  7. /**   
  8. * @Title: SecureActivity.java 
  9. * @Package com.xiaoma.policymanager.demo 
  10. * @Description: 权限验证类实现 
  11. * @author MZH 
  12. */ 
  13. public class SecureActivity extends Activity { 
  14.  
  15.     @Override 
  16.     protected void onResume() { 
  17.         super.onResume(); 
  18.         // Check to see if the device is properly secured as per the policy.  Send user 
  19.         // back to policy set up screen if necessary. 
  20.         Policy policy = new Policy(this); 
  21.         policy.readFromLocal(); 
  22.         if (!policy.isDeviceSecured()) { 
  23.             Intent intent = new Intent(); 
  24.             intent.setClass(this, PolicySetupActivity.class); 
  25.             intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | 
  26.                             Intent.FLAG_ACTIVITY_CLEAR_TASK); 
  27.             startActivity(intent); 
  28.             finish(); 
  29.         } 
  30.         setContentView(R.layout.activity_secure); 
  31.     } 

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