当应用进入后台时,安卓自动注销登录。

14
我希望能够检测到应用程序何时被发送到后台。有许多关于挂接HOME键的问题 - 我了解这只有通过注册为启动器应用程序才可能实现。
...但是...像往常一样,有客户想要特定的行为...
我们拥有一个高安全性需求的应用程序。客户希望每当应用程序由于任何原因(电话呼叫,HOME键,返回上一个活动)而进入后台时,应用程序都会注销服务器(澄清一下,我的意思是当屏幕上的前一个Activity不是我的应用程序活动之一)。
所以,如果我无法挂钩HOME键,还有什么其他选择?显然,仅挂钩onPause()是没有用的,因为它是与Activity相关的。
我们想出的“最佳”方法是在我们的Application类中保持一个Activity引用数组。 在每个Activity的onResume()中添加它到此数组中。 在onPause()中,我们删除它。 同样在onPause()中,我们枚举此数组,以查找是否有任何已注册的活动位于前台。 如果找不到前台活动,则用户被注销。
我对这个解决方案感到不满意,并希望能找到更好的方法。
8个回答

6

1
我刚刚在这个线程中添加了一条新评论,展示了一个更好的方法(在我看来),使用Application.ActivityLifecycleCallbacks以及@peceps的方法。请查看我的答案:https://dev59.com/Vm035IYBdhLWcg3wJcnT#13996042 - RPM

6

//使用服务

//在此中

@Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

      IntentFilter filter = new IntentFilter();
     filter.addAction(Intent.ACTION_SCREEN_OFF);
     filter.addAction(Intent.ACTION_CALL);
     filter.addAction(Intent.ACTION_ANSWER);

     registerReceiver(mIntentReceiver, filter);

}

// 然后在广播接收器中

private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if(action.equalsIgnoreCase("android.intent.category.HOME") )
            {
//logout logic
} 
else if(action.equalsIgnoreCase("android.intent.action.SCREEN_OFF") )
            {
//logout logic
}

else if(action.equalsIgnoreCase("android.intent.action.DIAL") )
            {
//logout logic
}
else if(action.equalsIgnoreCase("android.intent.action.CALL")){
/    /logout logic
}
}

我喜欢这里的思路,但是活动进入后台还有其他方法 - 例如,另一个活动将自己带到前台。 - Richard Le Mesurier

3

我处理这个问题的方法是,在我的活动关闭/暂停时存储一个时间戳。当另一个活动启动时,它读取时间戳,如果相差超过 x 秒,则执行注销操作。

如果您需要物理上执行注销操作(例如在远程服务器上),请在活动暂停时设置 AlarmManager,以便在 x 秒后注销。如果在它触发之前另一个活动启动,则可以取消此闹钟。


在您的活动中添加时间戳的想法真是太棒了! - Hashim Akhtar

1
或者你可以使用一个单例的共享对象,并创建单个的 onPause()onResume() 函数来获取/设置该共享对象上的数据。这些函数将在所有活动的 onPauseonResume 中使用。

1

我之前曾尝试解决同样的问题,但据我所知除了你现在使用的方法外,没有其他可行的方式。最佳的重写方法是使用onStart()和onStop(),这些方法可以捕获活动的真实可见性变化并计算您的活动堆栈计数以进行注销。


0

android:clearTaskOnLaunch 可能会有所帮助。当您进入后台时,它不会使您注销,但是您可以强制登录屏幕成为您返回时的第一个屏幕。


0

我不知道这是否能帮到你,但我会尝试以这种方式:

  1. 创建一个基本的Activity并重写它的onStop()方法以从服务器注销
  2. 我的应用程序的所有Activities都将扩展上述基类。

所以现在如果任何一个Activity进入onStop状态,它将注销服务器,无论该Activity如何进入后台

注意:但是,如果您通过调用finish停止任何Activity,它也将注销,因此您必须在那种情况下解决问题


谢谢 - 我理解了Android活动的生命周期 - 问题在于尝试找到一种绕过应用程序生命周期和Android设计师决定不让应用程序挂钩HOME按钮的方法。您在笔记中提到的逻辑正是我试图通过提问解决的问题。我正在寻找一种优雅的方法来解决这个问题。 - Richard Le Mesurier
没有问题,只需在你的 BaseActivity 中创建一个方法,在你完成 Activity 时将布尔值设置为 true,并在 BaseActivity 的 onStop 方法中检查该布尔值,根据该值进行登出或反之操作。 - ingsaurabh

0

这应该会有所帮助:

这是在Activity类中找到的一个方法

protected void onUserLeaveHint ()

    Since: API Level 3
    Called as part of the activity lifecycle when an activity is about to go into the background as the result of user choice. For example, when the user presses the Home key, onUserLeaveHint() will be called, but when an incoming phone call causes the in-call Activity to be automatically brought to the foreground, onUserLeaveHint() will not be called on the activity being interrupted. In cases when it is invoked, this method is called right before the activity's onPause() callback.
    This callback and onUserInteraction() are intended to help activities manage status bar notifications intelligently; specifically, for helping activities determine the proper time to cancel a notfication.

1
他指出Activities的方法不适用于他使用多个Activities。使用onPause或onUserLeaveHint并不重要,唯一真正的区别在于第二个方法触发的情况比第一个少。 - dtech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接