知道何时显示密码锁定

时间:2011-11-23 22:00:20

标签: android locking

我正在开发一个应用程序,当用户离开应用程序并返回时(无论是通过屏幕锁定,还是通过后面或主页按钮返回主屏幕),需要显示密码屏幕。我使用以下方法工作:

启动活动将在启动时调用密码检查,并且每个活动都将以下功能添加到其onPause方法中:

@Override
public void onPause() {
    super.onPause();

    if (!isFinishing()) {
    new PasscodeCheckTask(this.getApplicationContext(),this).execute();
    }
}

PassocdeCheckTask如下所示。它会检查屏幕是否已关闭或应用程序是否已不在后台

public class PasscodeCheckTask extends AsyncTask<Void, Void, Boolean> {

    public static final int CHECK_PASSCODE = 0;

    private Context mActivityApplicationContext;
    private Context mActivityContext;

    public PasscodeCheckTask(Context applicationContext, Context activityContext){
        mActivityApplicationContext = applicationContext;
        mActivityContext = activityContext;
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        Boolean result = false;

        if (!((PowerManager)mActivityApplicationContext.getSystemService(android.content.Context.POWER_SERVICE)).isScreenOn() ||
            !isAppOnForeground(mActivityApplicationContext)) {
            result = true;
        }
        return result;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        if (result) {
            // Start passcode activity to check for passcode
            /* CODE HERE */
            ((Activity)mActivityContext).startActivityForResult(intent, CHECK_PASSCODE);
        }
    }

    protected boolean isAppOnForeground(final Context context) {
        List<RunningAppProcessInfo> appProcesses = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getRunningAppProcesses();

        if (appProcesses == null) {
            return false;
        }

        final String packageName = context.getPackageName();
        for (RunningAppProcessInfo appProcess : appProcesses) {
            if ((appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) && 
                 appProcess.processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
}

Passcode活动在完成后完成,如果密码没有通过,调用活动将moveTaskToBackground(true)。这个系统运行得很漂亮,直到我在带有mikg ROM的HTC Evo上试用它。出于某种原因,appProcess.importance从未显示为IMPORTANCE_FOREGROUND。它始终是IMPORTANCE_BACKGROUND。因此,即使应用程序从未进入后台,也始终会显示密码。

我在那部手机上尝试了DropBox(它也有密码锁),而且效果很好。我似乎无法找到一种不同的方式来了解应用程序何时进入后台,或者是否从后台带回来。关于如何使这项工作的任何想法?

2 个答案:

答案 0 :(得分:4)

在每个活动的onStop()中,使用离开活动的时间更新静态数据成员。在每个活动的onStart()中,检查该时间,如果超过某个超时阈值,则显示您的身份验证活动。允许用户设置超时值,这样如果他们不想每隔几秒就被打扰一次,他们就可以控制它。

答案 1 :(得分:1)

我喜欢基于时间的方法,我一直在努力让这个以一种很好的方式工作。基于时间的方法效果很好。我上了一堂课以便于使用。

public class PinCodeCheck {

    private static long INIT_TIME           = 0;
    private static PinCodeCheck ref         = null;
    private static SharedPreferences values = null;

    private PinCodeCheck(Context context){
        values = context.getSharedPreferences("com.example.xxx", 0); //use your preferences file name key!
    }//end constructor

    public static synchronized PinCodeCheck getInstance(Context context) {
        if (ref == null){
            ref = new PinCodeCheck(context);
        } 
        return ref;
    }//end method 

    public void init(){
        PinCodeCheck.INIT_TIME = System.currentTimeMillis();    
    }//end method   

    public void forceLock(){
        PinCodeCheck.INIT_TIME = 0;     
    }//end method   

    public boolean isLocked(){
        long currentTime    = System.currentTimeMillis();
        long threshold      = values.getLong(Keys.PASSWORD_PROTECT_TIMEOUT, 30000); // check here, might change in between calls
        if (currentTime - PinCodeCheck.INIT_TIME > threshold){
            return true;
        }
        return false;       
    }//end method   
}//end class

<强> USAGE

private static PinCodeCheck check   = PinCodeCheck.getInstance(context);

@Override
public void onResume() {
    super.onResume();  

    if (check.isLocked()) { 
        showDialog();               
    }
}//end method 

@Override
public void onPause() {          
    super.onPause();

    check.init();
}//end method