Android實(shí)現(xiàn)屏幕鎖定源碼詳解
最近有朋友問(wèn)屏幕鎖定的問(wèn)題,自己也在學(xué)習(xí),網(wǎng)上找了下也沒太詳細(xì)的例子,看的資料書上也沒有有關(guān)屏幕鎖定程序的介紹,下個(gè)小決心,自己照著官方文檔學(xué)習(xí)下,現(xiàn)在做好了,廢話不多說(shuō),先發(fā)下截圖,看下效果,需要注意的地方會(huì)加注釋,有問(wèn)題的朋友可以直接留言,我們共同學(xué)習(xí)交流,共同提高進(jìn)步!直接看效果圖:
一:未設(shè)置密碼時(shí)進(jìn)入系統(tǒng)設(shè)置的效果圖如下:

二:設(shè)置密碼方式預(yù)覽:

三:密碼解密效果圖

四:九宮格解密時(shí)的效果圖

下面來(lái)簡(jiǎn)單的看下源碼吧,此處講下,這個(gè)小DEMO也是臨時(shí)學(xué)習(xí)下的,有講的不明白的地方請(qǐng)朋友直接批評(píng)指出,有錯(cuò)肯定改的,吼吼看代碼:
主控制類:
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: 屏幕鎖實(shí)現(xiàn)測(cè)試
* @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";
/**存儲(chǔ)配置信息的SP文件名*/
private static final String APP_PREF = "APP_PREF";
/**有未知屏幕ID時(shí)返回此標(biāo)識(shí)*/
private static final int UNKNOWN_SCREEN_ID = -1;
/**聲明組件*/
private Spinner mPasswordQualityInputField;
private EditText mPasswordLengthInputField;
private EditText mPasswordMinUppercaseInputField;
/**獲取配置操作類對(duì)象
*/
private Policy mPolicy;
/**當(dāng)前屏幕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為空,則跳轉(zhuǎn)到設(shè)置頁(yè)*/
if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) {
setScreenContent(R.layout.activity_policy_setup);
/**跳轉(zhuǎn)到配置詳情頁(yè)*/
} else {
setScreenContent(savedScreenId);
}
}
/**
* 設(shè)置屏幕方法實(shí)現(xiàn),詳細(xì)的可以自己看下,我也是邊參照官方文檔,邊學(xué)習(xí)的
* 有好想法有問(wèn)題的朋友們可以留言.我們一起學(xué)習(xí)
* @param screenId
*/ private void setScreenContent(final int screenId) {
/**記錄當(dāng)前屏幕ID,并預(yù)先存入本地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;
}
}
/**
* 關(guān)閉頁(yè)面時(shí)將當(dāng)前配置寫入本地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);
}
}
/**
* 重載返回鍵方法,如果已當(dāng)前屏幕為已設(shè)置密碼頁(yè),則展示詳情
*/
@Override
public void onBackPressed() {
if (mCurrentScreenId == R.layout.activity_view_policy) {
setScreenContent(R.layout.activity_policy_setup);
return;
}
super.onBackPressed();
}
/**
* 初始化化設(shè)置頁(yè)
*/
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 =
?。↙inearLayout) 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) {}
});
/**閱讀先前配置的相關(guān)信息*/
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("");
}
}
/**
* 初始化查看詳情頁(yè)
*/
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 =
?。↙inearLayout) findViewById(R.id.password_uppercase_view);
passwordMinUppercaseView.setVisibility(View.VISIBLE);
?。ǎ═extView) findViewById(R.id.policy_password_uppercase)).setText(
String.valueOf(mPolicy.getPasswordMinUpperCase()));
}
}
/**
* 設(shè)置導(dǎo)航信息
*/
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));
}
});
}
}
/**
* 監(jiān)聽器實(shí)現(xiàn),這個(gè)不多講了.
*/
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);
}
};
/**
* 監(jiān)聽器實(shí)現(xiàn),這個(gè)小馬也不多講了.
*/
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);
}
};
/**
* 設(shè)置激活按鈕不同狀態(tài)時(shí)的文本信息
* @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);
}
// 在關(guān)閉此頁(yè)時(shí),將配置信息寫入本地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: 用來(lái)獲取相關(guān)安全配置信息的類
* @author MZH */ public class Policy {
public static final int REQUEST_ADD_DEVICE_ADMIN = 1;
/**保存屏幕鎖相關(guān)參數(shù)的SP文件名*/
private static final String APP_PREF = "APP_PREF";
/**下面三個(gè)是往SP中存儲(chǔ)時(shí)的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;
/**
* 構(gòu)造器,在new此類對(duì)象時(shí),獲取系統(tǒng)級(jí)管理員對(duì)象 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);
}
/**
* 保存設(shè)備參數(shù)
*/
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文件中獲取密碼配置參數(shù)
*/
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; }
/**
* 獲取密碼長(zhǎng)度.
*
* @return
*/
public int getPasswordLength() { return mPasswordLength; }
/**
* 獲取字母密碼.
*
* @return
*/
public int getPasswordMinUpperCase() { return mPasswordMinUpperCase; }
/**
* 獲取設(shè)備管理的 ComponentName 對(duì)象.
*
* @return
*/
public ComponentName getPolicyAdmin() { return mPolicyAdmin; }
/**
* 判斷設(shè)備是否被激活.
*
* @return
*/
public boolean isAdminActive() {
return mDPM.isAdminActive(mPolicyAdmin);
}
public boolean isActivePasswordSufficient() {
return mDPM.isActivePasswordSufficient();
}
/**
* 判斷設(shè)備是否加安全
* @return
*/
public boolean isDeviceSecured() {
return isAdminActive() && isActiveP
asswordSufficient(); }
/**
* 在聲明的mDPM對(duì)象中進(jìn)行配置.
*/
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);
}
}
/**
* 下面這個(gè)類用來(lái)監(jiān)聽各種不同類型的設(shè)備管理事件,比如:改變密碼錯(cuò)誤密碼等等
*/
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();
}
}
}
權(quán)限驗(yàn)證類:
package com.xiaoma.policymanager.demo;
import android.app.Activity;
import android.content.Intent;
/**
* @Title: SecureActivity.java
* @Package com.xiaoma.policymanager.demo
* @Description: 權(quán)限驗(yàn)證類實(shí)現(xiàn)
* @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);
}
}
希望本文所述對(duì)你有所幫助,Android實(shí)現(xiàn)屏幕鎖定源碼詳解內(nèi)容就給大家介紹到這里了。希望大家繼續(xù)關(guān)注我們的網(wǎng)站!想要學(xué)習(xí)Android可以繼續(xù)關(guān)注本站。
相關(guān)文章
Android學(xué)習(xí)之Span的使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android中各種Span類的使用方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Android有一定的幫助,需要的可以參考一下2022-06-06
SwipeLayout框架實(shí)現(xiàn)側(cè)拉刪除編輯功能
這篇文章主要為大家詳細(xì)介紹了SwipeLayout框架實(shí)現(xiàn)側(cè)拉刪除編輯功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
Android開發(fā)優(yōu)化之Apk瘦身優(yōu)化指南
隨著業(yè)務(wù)快速發(fā)展,各種業(yè)務(wù)功能上線,版本不斷迭代,apk體積也越來(lái)越大,下面這篇文章主要給大家介紹了關(guān)于Android開發(fā)優(yōu)化之Apk瘦身優(yōu)化的相關(guān)資料,需要的朋友可以參考下2022-05-05
解決Android橫豎屏切換數(shù)據(jù)丟失問(wèn)題的方法
這篇文章主要為大家詳細(xì)介紹了Android橫豎屏切換數(shù)據(jù)丟失問(wèn)題的解決方法,感興趣的小伙伴們可以參考一下2016-05-05
Android編程設(shè)計(jì)模式之抽象工廠模式詳解
這篇文章主要介紹了Android編程設(shè)計(jì)模式之抽象工廠模式,結(jié)合實(shí)例形式詳細(xì)分析了Android抽象工廠模式的概念、原理、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下2017-12-12
Android?RecyclerChart其它圖表繪制示例詳解
這篇文章主要為大家介紹了Android?RecyclerChart其它圖表繪制示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Android如何讓APP無(wú)法在指定的系統(tǒng)版本上運(yùn)行(實(shí)現(xiàn)方法)
這篇文章主要介紹了Android如何讓APP無(wú)法在指定的系統(tǒng)版本上運(yùn)行(實(shí)現(xiàn)方法),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
Android Studio中使用lambda表達(dá)式的方法
這篇文章主要介紹了Android Studio中使用lambda表達(dá)式的方法,需要的朋友可以參考下2017-06-06
動(dòng)態(tài)添加LinearLayout的高度實(shí)例
下面小編就為大家?guī)?lái)一篇?jiǎng)討B(tài)添加LinearLayout的高度實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04

