如何检测用户在Android中有多个活动一段时间不活动

MJM*_*MJM 7 session android handle lockscreen

我知道同样的问题在这里,已经有人问过,并且有答案,但我对这个答案有疑问.

我的要求是,我想确定用户是否处于非活动状态5分钟,然后用户从应用程序中自动注销并上传登录并注销服务器上的日志.

我已经尝试了上面链接中的所有答案,但该答案适用于单个活动,但我想跟踪它以进行多项活动.

为此,我创建了抽象类

public abstract class SessionTimeOutActivity extends BaseActivity {

    public static final long DISCONNECT_TIMEOUT = 1000 * 60; // 5 min = 5 * 60 * 1000 ms

    private static Handler disconnectHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            Log.d("SessionTimeOutActivity", "disconnectHandler");

            return false;
        }
    });

    private Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {
            // Perform any required operation on disconnect
            Log.d("SessionTimeOutActivity", "disconnectCallback");


            Toast.makeText(getApplicationContext(), "Session time out", Toast.LENGTH_LONG).show();
            Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
            startActivity(intent);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

            finish();

        }
    };

    public void resetDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
        disconnectHandler.postDelayed(disconnectCallback, DISCONNECT_TIMEOUT);
    }

    public void stopDisconnectTimer() {
        disconnectHandler.removeCallbacks(disconnectCallback);
    }

    @Override
    public void onUserInteraction() {
        Log.d("SessionTimeOutActivity", "onUserInteraction");
        resetDisconnectTimer();
    }

    @Override
    public void onResume() {
        super.onResume();
//        resetDisconnectTimer();
    }

    @Override
    public void onStop() {
        super.onStop();
//        stopDisconnectTimer();
    }


}
Run Code Online (Sandbox Code Playgroud)

app中的其他活动

    public class MenuActivtyNav extends SessionTimeOutActivity{
.....
}
Run Code Online (Sandbox Code Playgroud)

MenuActivity

 public class MenuActivty extends SessionTimeOutActivity{
....
}
Run Code Online (Sandbox Code Playgroud)

问题是

1)在锁定屏幕中自动注销不起作用,它不调用disconnectCallback

2)使用应用程序时,它会显示Toast消息"Session time out"

Tpo*_*6oH 7

让我们首先了解您的代码没有按照您的意愿行事的原因.

问题1.您应该避免在Android上的活动中长时间运行任务,尤其是当它们不可见时,因为系统可能会终止您的活动或应用程序进程,因此代码将无法运行.

问题2.每个活动都会将disconnect回调发布到您的处理程序,如果用户与第二个活动进行交互,第一个活动的回调将不会被重置并触发.

解.

现在让我们考虑解决这个问题的方法.最好有一个地方来跟踪不活动.它可以是单例,也可以使用应用程序对象.并分别处理2个案例:第一个是您的用户在应用程序内部并且没有使用它而另一个是您的用户不在应用程序中时.

对于第一个目标,您可以采用与当前目标类似的方法,但disconnectCallback在应用程序中进行共享.将处理程序,回调和重置回调逻辑移动到您的Application类并制作您的

@Override
public void onUserInteraction()
Run Code Online (Sandbox Code Playgroud)

打电话resetCallback申请.这将使所有活动使用相同的回调并解决问题2.

对于第二个目标,您可以使用Activity Lifecycle Callbacks.每次暂停活动时都会保存时间戳.然后,每次恢复活动时,将此时间戳与恢复时间进行比较,如果大于5分钟,则注销用户并路由到登录屏幕.它将解决问题1.您需要保留此时间戳,因为应用程序可能被系统杀死,并且内存中共享的所有内容都将被删除.例如,使用共享首选项.

最后一件事,当应用程序进入后台时,您需要取消回调.您可以在onActivityPaused(Activity activity)活动回调中执行此操作,在您将触发第二种情况的逻辑的位置.