118 votes

Comment détecter l'INACTIVITÉ de l'UTILISATEUR dans android

L'utilisateur commence MyAPP et dans les journaux. Sélectionne le Délai d'expiration de Session sera de 5 minutes. N'certaines opérations sur l'app.......(tous en premier plan) Maintenant, l'Utilisateur apporter Myapp à fond et commence une autre application ----> Compte à rebours commence et se déconnecte l'utilisateur au bout de 5 minutes D'utilisateur OU ÉTEINDRE l'écran ----> Compte à rebours commence et se déconnecte l'utilisateur au bout de 5 minutes

Ma Question:

Je veux que ce même comportement, même lorsque l'application est au premier plan, mais l'utilisateur n'interagit pas avec l'application pour un long temps de dire 6-7 minutes... Supposons que l'écran est allumé tout le temps... je veux détecter genre d'INACTIVITÉ de l'UTILISATEUR (Pas d'interaction avec l'app même si l'application est au premier plan) et de lancer mon décompte.

Merci à l'avance.

120voto

gfrigon Points 573

Je suis venu avec une solution que je trouve assez simple basé sur Fredrik wallenius programme de réponse. Cette base de l'activité de la classe qui doit être prolongé de toutes les activités.

public class MyBaseActivity extends Activity {

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

    private Handler disconnectHandler = new Handler(){
        public void handleMessage(Message msg) {
        }
    };

    private Runnable disconnectCallback = new Runnable() {
        @Override
        public void run() {
            // Perform any required operation on disconnect
        }
    };

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

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

    @Override
    public void onUserInteraction(){
        resetDisconnectTimer();
    }

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

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

108voto

Fredrik Wallenius Points 1535

Je ne sais pas d'un moyen de suivre l'inactivité, mais il y a un moyen de suivre l'activité de l'utilisateur. Vous pouvez prendre un callback appelé onUserInteraction() dans vos activités, qui est appelée à chaque fois que l'utilisateur n'a aucune interaction avec l'application. Je vous suggère de faire quelque chose comme ceci:

@Override
public void onUserInteraction(){
    MyTimerClass.getInstance().resetTimer();
}

Si votre application contient plusieurs activités, pourquoi ne pas mettre cette méthode en résumé super classe (extension de l'Activité) et puis tous vous les activités de l'étendre.

12voto

AKh Points 1398
MyApplciation extents Application(){
  private int lastInteraction;
  private Boolean isScreenOff = false; 
  public void onCreate(){
  super.onCreate();
  ......   
  startUserInactivityDetectThread(); // start the thread to detect inactivity
     new ScreenReceiver();  // creating receive SCREEN_OFF and SCREEN_ON broadcast msgs from the device.
  }

  public void startUserInactivityDetectThread(){
    new Thread(new Runnable() {
       public void run() {
         while(true) {
            Thread.sleep(15000); // checks every 15sec for inactivity
              if(isScreenOff || getLastInteractionTime > 120000 ||  !isInForeGrnd)
              {
                //...... means USER has been INACTIVE over a period of
                // and you do your stuff like log the user out 
              }
            }
         }).start();
       }

    public long getLastInteractionTime() {
       return lastInteractionTime;
    }

    public long setLastInteractionTime(int lastInteraction) {
       lastInteractionTime = lastInteraction;
    }

    private class ScreenReceiver extends BroadcastReceiver {

    protected ScreenReceiver() {
       // register receiver that handles screen on and screen off logic
       IntentFilter filter = new IntentFilter();
       filter.addAction(Intent.ACTION_SCREEN_ON);
       filter.addAction(Intent.ACTION_SCREEN_OFF);
       registerReceiver(this, filter);
    }

    @Override
    public void onReceive(Context context, Intent intent) {
       if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
         isScreenOff = true;
       } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
           isScreenOff = false;
       }
      }
      }
     }

isInForeGrnd ===> logique n'est pas montré ici, comme c'est hors de portée de la question

12voto

soenke Points 137
@Override
public void onUserInteraction() {
    super.onUserInteraction();
    delayedIdle(IDLE_DELAY_MINUTES);
}

Handler _idleHandler = new Handler();
Runnable _idleRunnable = new Runnable() {
    @Override
    public void run() {
        //handle your IDLE state
    }
};

private void delayedIdle(int delayMinutes) {
    _idleHandler.removeCallbacks(_idleRunnable);
    _idleHandler.postDelayed(_idleRunnable, (delayMinutes * 1000 * 60));
}

2voto

divide by zero Points 848

Dans mon activité de la classe de base, j'ai créé la classe protégée:

protected class IdleTimer
{
    private Boolean isTimerRunning;
    private IIdleCallback idleCallback;
    private int maxIdleTime;
    private Timer timer;

    public IdleTimer(int maxInactivityTime, IIdleCallback callback)
    {
        maxIdleTime = maxInactivityTime;
        idleCallback = callback;
    }

    /*
     * creates new timer with idleTimer params and schedules a task
     */
    public void startIdleTimer()
    {
        timer = new Timer();            
        timer.schedule(new TimerTask() {

            @Override
            public void run() {             
                idleCallback.inactivityDetected();
            }
        }, maxIdleTime);
        isTimerRunning = true;
    }

    /*
     * schedules new idle timer, call this to reset timer
     */
    public void restartIdleTimer()
    {
        stopIdleTimer();
        startIdleTimer();
    }

    /*
     * stops idle timer, canceling all scheduled tasks in it
     */
    public void stopIdleTimer()
    {
        timer.cancel();
        isTimerRunning = false;
    }

    /*
     * check current state of timer
     * @return boolean isTimerRunning
     */
    public boolean checkIsTimerRunning()
    {
        return isTimerRunning;
    }
}

protected interface IIdleCallback
{
    public void inactivityDetected();
}

Ainsi, dans onResume méthode, vous pouvez spécifier l'action dans votre rappel de ce que vous désirez faire avec elle...

idleTimer = new IdleTimer(60000, new IIdleCallback() {
            @Override
            public void inactivityDetected() {
                ...your move...
            }
        });
        idleTimer.startIdleTimer();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X