Android实现屏幕锁定源码详解

 更新时间:2016年10月21日 15:03:18   作者:Android小子  
本篇文章主要介绍了Android实现屏幕锁定源码详解,屏幕锁定是一个很有用的功能,有需要的可以了解一下。

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

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

 

二:设置密码方式预览:

三:密码解密效果图

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

下面来简单的看下源码吧,此处讲下,这个小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);
  }
  @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 (!mPolic
  y.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);
  }
  }

配置操作类:

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() && isActiveP
  asswordSufficient();   }
  /**
  * 在声明的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();
  }
  }
  }

权限验证类:

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);
}
}

希望本文所述对你有所帮助,Android实现屏幕锁定源码详解内容就给大家介绍到这里了。希望大家继续关注我们的网站!想要学习Android可以继续关注本站。

相关文章

  • Android学习之Span的使用方法详解

    Android学习之Span的使用方法详解

    这篇文章主要为大家详细介绍了Android中各种Span类的使用方法,文中的示例代码讲解详细,对我们学习Android有一定的帮助,需要的可以参考一下
    2022-06-06
  • SwipeLayout框架实现侧拉删除编辑功能

    SwipeLayout框架实现侧拉删除编辑功能

    这篇文章主要为大家详细介绍了SwipeLayout框架实现侧拉删除编辑功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Android开发优化之Apk瘦身优化指南

    Android开发优化之Apk瘦身优化指南

    随着业务快速发展,各种业务功能上线,版本不断迭代,apk体积也越来越大,下面这篇文章主要给大家介绍了关于Android开发优化之Apk瘦身优化的相关资料,需要的朋友可以参考下
    2022-05-05
  • 解决Android横竖屏切换数据丢失问题的方法

    解决Android横竖屏切换数据丢失问题的方法

    这篇文章主要为大家详细介绍了Android横竖屏切换数据丢失问题的解决方法,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android编程设计模式之抽象工厂模式详解

    Android编程设计模式之抽象工厂模式详解

    这篇文章主要介绍了Android编程设计模式之抽象工厂模式,结合实例形式详细分析了Android抽象工厂模式的概念、原理、使用方法及相关注意事项,需要的朋友可以参考下
    2017-12-12
  • Android RecyclerChart其它图表绘制示例详解

    Android RecyclerChart其它图表绘制示例详解

    这篇文章主要为大家介绍了Android RecyclerChart其它图表绘制示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Android实现手写板功能

    Android实现手写板功能

    这篇文章主要为大家详细介绍了Android实现手写板功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • Android如何让APP无法在指定的系统版本上运行(实现方法)

    Android如何让APP无法在指定的系统版本上运行(实现方法)

    这篇文章主要介绍了Android如何让APP无法在指定的系统版本上运行(实现方法),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Android Studio中使用lambda表达式的方法

    Android Studio中使用lambda表达式的方法

    这篇文章主要介绍了Android Studio中使用lambda表达式的方法,需要的朋友可以参考下
    2017-06-06
  • 动态添加LinearLayout的高度实例

    动态添加LinearLayout的高度实例

    下面小编就为大家带来一篇动态添加LinearLayout的高度实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04

最新评论