1. ホーム
  2. android

[解決済み] Androidでユーザーの非アクティブを検出する方法

2022-05-17 13:40:30

質問

ユーザーが私のアプリを起動し、ログインしています。

セッションタイムアウトを5分に選択します。

アプリに対していくつかの操作を行います。(すべてフォアグラウンドで)

今度はユーザーがMyappをバックグラウンドにし、他のアプリを起動する。

----> カウントダウンタイマーを開始し、5分後にユーザーをログアウトさせる。

またはユーザーが画面を消した

----> カウントダウンタイマーを開始し、5分後にユーザーをログアウトさせる。

アプリがフォアグラウンドにありながら、ユーザーが長時間(6~7分)アプリを操作しない場合でも、同じ動作をさせたいのです。画面は常にオンになっていると仮定します。私は一種の検出をしたい ユーザーの非アクティブ (アプリがフォアグラウンドにあるにもかかわらず、アプリとのインタラクションがない)を検出し、カウントダウンタイマーを起動させたい。

どのように解決するのですか?

public class MyApplication extends Application {
      private int lastInteractionTime;
      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() {
          @Override
          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 void setLastInteractionTime(int lastInteractionTime) {
        this.lastInteractionTime = lastInteractionTime;
      }

      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 ===>のロジックは質問の範囲外なので、ここでは表示しません。

以下のデバイスコードを使用することで、CPUへのロックを解除することができます。

  if(isScreenOff || getLastInteractionTime()> 120000 ||  !isInForeGrnd)
    {
      //...... means USER has been INACTIVE over a period of
      // and you do your stuff like log the user out 

      PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

      boolean isScreenOn = pm.isScreenOn();
      Log.e("screen on.................................", "" + isScreenOn);

      if (isScreenOn == false) {

        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "MyLock");

        wl.acquire(10000);
        PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyCpuLock");

        wl_cpu.acquire(10000);
      }
    }