Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect user is inactivity for some time with multiple activity in android

I know same question is here, already asked by some one and there is answer for that,but i have issue with that answer.

My requirement is,I want to identify if user is inactivity for 5 minute then user get auto logout from app and upload the the sign in and sign out log on server.

I have tried all answer from above link,but that answer are working for Single activity,but i want to track it for multiple activity.

For that i have created abstract class

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();
    }


}

Other activities in app

    public class MenuActivtyNav extends SessionTimeOutActivity{
.....
}

MenuActivity

 public class MenuActivty extends SessionTimeOutActivity{
....
}

Issue is

1) In Lock screen Auto logout not working,it not calling disconnectCallback

2) While using app it shows toast message "Session time out"

like image 738
MJM Avatar asked May 29 '18 14:05

MJM


People also ask

How do you detect user inactivity in flutter?

And a good way to do this is to use the mixin WidgetsBindingObserver on your LandingPage of the app. The mixin provides you with an enum AppLifecycleState which can have 4 values, detached, inactive, paused and resumed which depicts the current state of the app.

How many activities should my Android app have?

Typically, one activity in an app is specified as the main activity, which is the first screen to appear when the user launches the app. Each activity can then start another activity in order to perform different actions.


1 Answers

Let's start with understanding the reasons why your code is not doing what you want.

Problem 1. You should avoid having long running tasks in your activities on android, especially when they are not visible because the system can kill your activity or application process, so the code won't run.

Problem 2. Every activity posts the disconnect callback to your handler, and in case when user is interacting with second activity the first activity's callback won't be reset and will trigger.

Solution.

Now let's think about an approach to solve this. It would be better to have one place to track the inactivity. It can be a singleton or you can use application object. And handle 2 cases separately: first one is if your user is inside the app and is not using it and another one is when your user is out of the app.

For the first goal you can have approach similar to your current one, but make shared disconnectCallback in the application. Move the handler, callback and reset callback logic to your Application class and make your

@Override
public void onUserInteraction()

call resetCallback on the Application. This will make all Activities use the same callback and solve problem 2.

For the second goal, you can make use of the Activity Lifecycle Callbacks. Every time you have your activity paused save the timestamp. Then every time the activity is resumed compare this timestamp with the resume time, if it is greater than 5 minutes, then log out your user and route to login screen. It will solve problem 1. You'll need to persist this timestamp because the application can be killed by the system and everything shared in memory will be wiped off. Use shared preferences for example.

And the last thing, you'll need to cancel your callbacks when the app is going to background. You can do it in onActivityPaused(Activity activity) of your activity callbacks, in the same place where you'll be triggering logic for the second case.

like image 72
TpoM6oH Avatar answered Nov 10 '22 00:11

TpoM6oH