最近在一个视频项目中遇到了很多屏幕锁定的问题,小马自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,从之前写的文章中抽过来放研究院中,希望能帮助更多想了解或学习屏幕锁的朋友们学习研究,自己照着官方文档学习下,现在做好了,小马废话不多说,先发下截图,看下效果,需要注意的地方小马会加注释,有问题的朋友可以直接留言,我们共同学习交流,共同提高进步!直接看效果图:
一:未设置密码时进入系统设置的效果图如下:
二:运行DEMO,进入应用时:
三:设置密码方式预览:
四:只设置密码保护时的效果图
五:密码解密效果图
六:设置九宫格加密时的效果图
七:九宫格解密时的效果图
八:解密成功后,进入我们手机系统的图
下面来简单的看下源码吧,此处讲下,这个小DEMO也是小马临时学习下的,有讲的不明白的地方请朋友直接批评指出,有错肯定改的,吼吼..看代码:
主控制类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 |
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); } } |
配置操作类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
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(); } } } |
权限验证类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
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); } } |
一起学习,一起进步,如有小马讲不好的地方,请朋友直接批评指点..小马定感谢…谢谢..加油加油!
- 本文固定链接: https://www.xuanyusong.com/archives/1665
- 转载请注明: 小马果 于 雨松MOMO程序研究院 发表
捐 赠如果您愿意花20块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
有源码吗?
楼主太强大了、我顶一个、学习ING,谢谢、
谢谢支持…一起努力学习!加油加油,安卓很快就超IOS了!!!!
咦,这篇的源码在哪里下载呢?
呵呵,源码在我51下载….http://mzh3344258.blog.51cto.com/1823534/748998……谢谢,加油!!!
呵呵,源码在我51下载….http://mzh3344258.blog.51cto.com/1823534/748998……谢谢,加油!!!
呵呵,源码在我51下载 http://mzh3344258.blog.51cto.com/1823534/748998 谢谢,加油!!!
为什么没有早一点看到呢?
呵呵,这是系统的,认真研究,屏幕锁定就没太大问题啦….加油!!!
学习了
加油加油!!!
感谢小马的分享哈。。 哇咔咔