将密码屏幕添加到设备休眠时重新锁定的应用程序?

Adding a PASSWORD screen to app that re-locks when device sleeps?

我有一个应用程序可以自动锁定(需要密码输入屏幕)...

a) when the app starts for the first time
b) when another app is started and takes over the device
c) when the device "sleeps" automatically
d) when the user "sleeps" the device manually
(note: with c & d, if the user "awakens" the app within 5 seconds, it does NOT ask for the password)

我也想为我正在编写的应用程序执行此操作,因此我创建了一个具有必要验证步骤的 activity (PasswordActivity) 并使其正常工作。

我最初将它放在 MainActivityONCREATE 中(已在 AndroidManifest 中启动)。这似乎工作正常。但随后开始重新锁定功能。因此尝试将其移动到 ONSTARTONRESUME。但是当我的应用程序中的另一个 ACTIVITY 获得焦点时,或者屏幕旋转时,PasswordActivity 再次触发。那不行。

在这里我发现了一个帖子,建议在 Manifest 中将其设置为 LAUNCHER 应用程序,然后当密码正确时,调用 MainActivity。这似乎效果更好......但随后 运行 出现了一个问题,即只有当用户按下主屏幕上的后退按钮(我假设停止我的应用程序)并再次启动应用程序时,它才 "re-locks" 。虽然没有发现另一个 APP 接管了设备。

所以基于此,在查看了我能找到的所有关于生命周期的文档之后(尽管其中大部分是基于 ACTIVITY,而不是基于应用程序)不确定当应用程序本身失去焦点时如何捕捉(另一个应用程序接管)以及如何处理自动或手动睡眠(上面的 C 和 D)以及时间延迟检查。我假设它将是多个调用或步骤的组合,但目前不确定具体是哪些。

有什么建议吗?

我想我是根据一些建议和一些研究得出的结论。我在这里发布我的解决方案以防它可以帮助其他人,有人看到我没有看到或遇到的明确缺陷,或者有人有一些其他输入可以改进它。

如前所述,据我所知,最大的问题是没有任何内置函数调用可以确定 "your app" 何时不在前台。 onPauseonResume 是基于 activity 的,而不是基于应用程序的...因此在您的应用程序中从 activity 更改为 activity 甚至屏幕旋转都会触发它们.

为了解决这个问题...我创建了一个名为 gv.appPauseTime 的全局变量。我创建了两个独立的通用实用函数,我可以在我的应用程序的任何地方调用。

public static void lockAppStoreTime() {
    gv.appPauseTime=new Date();
}

public static void lockAppCheck(Activity act) {
    boolean bLock=false;

    // Check to see if this is the first time through app       
    if (gv.appPauseTime==null) {
       bLock = true;
    } else {
       Date currTime = new Date();
       long diffMillis = currTime.getTime() - gv.appPauseTime.getTime();
       long diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffMillis);

       // Lock app if 120 seconds (2 minutes) has lapsed
       if (diffInSec > 120) {
           bLock=true;
       }
    }

    gv.appLastPause = new Date();
    if (bLock) {
       Intent j = new Intent(act, PasswordActivity.class);
       act.startActivity(j);
    }
}

在每个 activity 中,我都像这样创建(或修改)onPauseonResume...

@Override
public void onPause(){
    super.onPause();
    Util.lockAppStoreTime();
}

@Override
public void onResume(){
    super.onResume();
    Util.lockAppCheck(this);
}

onPause 触发时,它存储当前日期(时间)。当 onResume 在任何函数中触发时,它会将当前日期(时间)与存储的日期(时间)进行比较。如果 120 秒(2 分钟)过去了,它会显示 PasswordActivity 以验证密码。它在调用 PasswordActivity 之前 "store" 当前日期(时间),这样它就不会一直重复它。

基本上,如果在 activity 暂停和任何 activity 之间有 2 分钟的间隔,在我的应用程序中,恢复(或开始),它会提示输入密码。如果用户打开不同的APP,然后returns到我的APP...再次,如果至少间隔2分钟,则要求输入密码。如果用户关机或关闭应用程序,则重新启动也会触发密码。

我选择了 2 分钟,因为这在我们的应用程序中似乎一般 "time lapse"。当然,那也是可以改变的。

到目前为止,还不错。希望这对其他人有帮助。