功能:

1.应用程序程序中设置了密码锁,每当用户打开应用时,要弹出密码输入界面;

2.当用户按住home键,将程序隐在后台而非退出,经过一段时间后,再重新启动,也要弹出密码输入界面;

3.当应用在前台的时候,用户按住power电源键,关闭屏幕后,再点亮屏幕,这个时候也要弹出密码输入界面

实现方式:


1.针对功能1,每次启动应用进入主界面时,判断是否需要弹出密码输入界面;

2.关键点在于怎么判断程序是否处在前台跟后台。

判断方法:

public static boolean isAppOnForeground(Context context) {
     ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
     String packageName = context.getApplicationContext().getPackageName();
     List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
     if(appProcesses == null)
          return false;
     for(RunningAppProcessInfo appProcess : appProcesses) {
          if(appProcess.processName.equals(packageName) && appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
               return true;
          }
     }
     return false;
}

其主要原理是:获取当前正在运行的所有进程,根据进程名字进行逐一比较(默认应用程序进程名字为包名),

并且当前进程的 importance 为IMPORTANCE_FOREGROUND,及该进程处在前台。

protected void onStop() {
     super.onStop();
     if(!isAppOnForeground(this)) {
          mIsActive = false;
     }
}

在相应Activity的onRestart()中判断:

protected void onRestart() {
     if(!mIsActive) {
          mIsActive = true;
          //弹出密码框输入界面
          //.………...
     }
}

3.监听锁屏广播:ACTION_SCREEN_ON

public static boolean IS_FOREGROUND = false;

public class ScreenActionReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
     String action = intent.getAction();
     if (action.equals(Intent.ACTION_SCREEN_ON)) {
               //用户点亮屏幕
               //判断是否需要弹出密码锁来
               if(IS_FOREGROUND) {
                    //如果应用程序恰好处在前台,则弹出密码锁界面来
               }
         } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
               //用户关闭屏幕
     }
}

if(mScreenActionReceiver == null) {
     mScreenActionReceiver = new ScreenActionReceiver();
     IntentFilter screenfilter = new IntentFilter();
     screenfilter.addAction(Intent.ACTION_SCREEN_OFF);
     screenfilter.addAction(Intent.ACTION_SCREEN_ON);
     registerReceiver(mScreenActionReceiver, screenfilter);
}


注意点:


在收到屏幕点亮通知的时候,要判断应用程序是否在前台,如果不在前台,则不要把密码锁界面掉出来。


在这个时候调用isAppOnForeground()方法,发现会返回true,也就是程序在收到这个广播的时候,


系统认为应用跑到foreground来了。


解决方法:在Application中设置一个变量 IS_FOREGROUND ,


在Activity的onCreate()、onStop()、onRestart()中进行判断并设置该变量的值。