最近有朋友问屏幕锁定的问题,小马自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,下个小决心,自己照着官方文档学习下,现在做好了,小马废话不多说,先发下截图,看下效果,需要注意的地方小马会加注释,有问题的朋友可以直接留言,我们共同学习交流,共同提高进步!直接看效果图:
一:未设置密码时进入系统设置的效果图如下:
<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 && 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<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()));
mPasswordLengthInputField.setText("");
if (mPolicy.getPasswordMinUpperCase() > 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 > 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() && 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 {
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,如需转载请自行联系原作者