最近做了一个demo——功能是给自己的应用加锁,访问的时候需要输入密码,并且每次锁屏再开之后都需要重新输入密码。
主要思路:
- 设置一个全局变量表示当前应用的状态(布尔值:已锁定|已解锁),在每个Activity显示之前进行状态判断,如果当前为锁定状态,则终止显示,跳转到密码界面。
- 在密码界面输入正确的密码之后,将应用状态改为已解锁,并返回继续显示之前的Activity;否则继续要求输入密码。
- 注册一个广播接收,监听系统的锁屏事件,有锁屏事件发生时,将应用的状态改为已锁定。(即每次锁屏之后需要重新输入密码)
具体实现:
1. 全局变量的实现
1.1 用一个全局的静态变量当然是OK的。
1.2 不过在Android上我们可以用一个更“优雅”一点的实现:利用Android的Application对象(文档)。
- 写一个MyApplication类,继承自android.app.Application。
- 在MyApplication中定义一个状态变量,并且在onCreate()方法中进行初始化。
- 在AndroidMainfest.xml中在标签添加name属性,值为MyApplication的完整类名。
android:name="barry.demo.passwordApp.MyApplication"
- 则在此标签下的所有Activity中,都可以用MyApplication myApplaction = (MyApplication) getApplication();来获取MyApplication的实例并使用或修改其中的变量了。
2. 根据状态判断是否需要输入密码
由于onResume()方法是Activity每次显示或者重绘都会调用的方法(见Activity的生命周期),所以可以在此方法中进行状态判断。
具体做法可以是:
-
写一个用于输入密码的界面PasswordActivity;
-
写一个BaseActivity,在其中的onResume()方法中写入判断代码,然后其余所有Activity都继承自此BaseActivity——当然,密码界面PasswordActivity除外。
BaseActivity大概长这个样子:
- public class BaseActivity extends Activity {
- MyApplication myApplaction;
- protected void onResume() {
- super.onResume();
- myApplaction = (MyApplication) getApplication();
- if (myApplaction.isLocked) {//判断是否需要跳转到密码界面
- Intent intent = new Intent(this, PasswordActivity.class);
- startActivity(intent);
- }
- };
- }
PasswordActivity大概长这个样子:
- public class PasswordActivity extends Activity {
- MyApplication myApplaction;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_password);
- myApplaction = (MyApplication) getApplication();
- final EditText editTextPassword = (EditText) findViewById(R.id.editTextPassword);
- findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- String password = editTextPassword.getText().toString();
- if (password != null && password.equals(myApplaction.password)) {
- Toast.makeText(PasswordActivity.this, "密码正确!", Toast.LENGTH_SHORT).show();
- myApplaction.isLocked = false;
- PasswordActivity.this.finish();
- } else {
- Toast.makeText(PasswordActivity.this, "密码错误!", Toast.LENGTH_SHORT).show();
- editTextPassword.setText("");
- }
- }
- });
- }
- }
3. 监听锁屏事件
经过以上两步,就可以实现应用的加锁了——在打开的应用的时候,就会自动跳转到密码界面,输入密码之后再进入内容Activity。——但是这只会在程序打开的时候输入一次密码,如果程序没有彻底关闭,那么把手机锁屏之后再打开,依然还是不需要输入密码。
要实现在手机锁屏之后再打开就要求密码,就必须要监听手机的锁屏事件了,在锁屏之后把应用状态改为锁定,这样再打开就会重新要求输入密码了。
3.1 监听锁屏的实现
诸如系统开机、锁屏、开屏、联网状态改变、有电话进来、有短息进来、系统电量过低等等,各种系统状态发生改变的时候,Android系统本身都会发一个广播。
我们要做的,就是要注册一个广播接受器,用其监听系统广播,当发现有锁屏事件发生的时候更改应用的状态。
由于这个广播接受器应该是启动应用时就创建的,而且是属于应用全局的,所以我们把它创建在MyAppLication类中,在MyApplication的onCreate()方法中进行初始化,在onTerminate()方法中取消注册。
3.2 构建广播接受器
构建一个广播接受器很简单,只需要继承android.content.BroadcastReceiver类,并且实现其中的onReceive()方法就好,在onReceive()中做接到广播之后的处理。
- class LockScreenReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- /* 在这里处理广播 */
- if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- isLocked = true;//把应用状态设为锁定
- }
- }
- }
3.3 注册广播
构建一个IntentFilter过滤器,在其中添加需要接收的广播类型,然后调用Context的registerReceiver方法。
- //注册
- receiver = new LockScreenReceiver();
- filter = new IntentFilter();
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- this.registerReceiver(receiver, filter);
- //取消注册
- this.unregisterReceiver(receiver);
至此,一个输入密码才能访问的应用demo就基本OK了。
Demo代码下载: 地址
界面比较丑陋,有时间再改一下。