Начало и конец приложения для Android

У меня есть приложение, которое отслеживает активность пользователя в приложении, которое включает время и т.д. Теперь, если пользователь открыл приложение, он запустит сеанс и пока пользователь в этом приложении не продолжит сеанс, он может переключиться на несколько действий. Теперь он переключается на другое приложение, его сеансовый журнал должен быть остановлен и записан в файл

Что я пробовал

Я создал одно базовое действие и При возобновлении события, если счетчик равен нулю, я запускаю счетчик сеанса и счетчика и В событии остановки, я декремент счетчика, и если счетчик равен нулю, я останавливаю сеанс

Но это не будет рассчитать фактическую проблему отслеживания, поскольку андроид не останавливает активность, поскольку пользователь переключается на другое приложение.

Итак, есть ли способ достичь такой цели.

Дополнительно:

Если мы можем активировать активность приложения на экране, чтобы событие можно было использовать для запуска или завершения сеанса.

Ответ 1

Я могу представить два способа сделать это:

Вариант 1:

Вы можете создать службу, которая сканирует текущее приложение на переднем плане и посмотреть, является ли это вашей деятельностью. Вот какой код вы можете использовать, я взял его из другого ответа:

Существует простой способ получить список запущенных задач из Служба ActivityManager. Вы можете запросить максимальное количество задач работает по телефону, и по умолчанию текущая активная задача вернулся первым.

После этого вы можете получить объект ComponentName, запросив topActivity из вашего списка.

Вот пример.

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);

     // get the info from the currently running task
     List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1); 

     Log.d("topActivity", "CURRENT Activity ::"
             + taskInfo.get(0).topActivity.getClassName());

     ComponentName componentInfo = taskInfo.get(0).topActivity;
   componentInfo.getPackageName();

Вам понадобится следующее разрешение на ваш манифест:

<uses-permission android:name="android.permission.GET_TASKS"/>

Ссылка на ответ: Android: Как я могу получить текущую активность переднего плана (из службы)?

Вы можете вызывать это каждую секунду или меньше, чтобы определить, активно ли ваше приложение. Обратите внимание, что это устарело и не рекомендуется использовать для такого рода вещей, согласно официальной документации:

getRunningTasks()

Примечание. Этот метод предназначен только для отладки и представления задачи интерфейсов управления. Это никогда не должно использоваться для основной логики в приложении, например, выбор между различными типами поведения о найденной здесь информации. Такое использование не поддерживается и будет вероятно, переломится в будущем. Например, если несколько приложений могут в то же время активно работать, допущения, сделанные в отношении смысл данных здесь для целей управления будет неверно.


Вариант 2:

Второй вариант - создать класс, который расширяет Application с помощью флага, например isAppRunning, который будет истинным или ложным, если ваше приложение находится на переднем плане или нет:

public class MyAppContext extends Application {

   public boolean isAppRunning = true;

   public void setIsAppRunning(boolean v){
      isAppRunning = v;
   }

   public boolean isAppRunning(){
      return isAppRunning;
   }

}

Затем на вашем AndroidManifest.xml вам нужно добавить этот класс, чтобы он использовался, когда ваше приложение запускается. Просто добавьте android:name=".MyAppContext" в тег приложения:

<application
        android:name=".MyAppContext"

Теперь в каждом действии, которое у вас есть, вы должны переопределить onResume() и onPause() и установить флаг в соответствующее значение:

class BaseActivity extends Activity {


    @Override
    protected void onResume() {
        super.onResume();
        ((MyAppContext)getApplication()).setIsAppRunning(true);
    }

    @Override
    protected void onPause() {
        ((MyAppContext)getApplication()).setIsAppRunning(false);
        super.onPause();
    }
}

Таким образом, каждый раз при запуске Activity значение isAppRunning в MyAppContext будет true, когда вы выйдете из Activity, оно будет false, но если откроется другое действие (например, если вы нажали кнопку "Назад", чтобы вернуться к предыдущему действию), значение будет немедленно true снова.

Когда вы закончите все свои действия, ни один из методов onResume() не будет вызван, и все методы onPause() будут вызваны так, что isAppRunning будет false, и вы знаете, что ваш Activity больше не включен на переднем плане.

Итак, повторите, если isAppRunning true ваше приложение находится на переднем плане (запустите отслеживание сеанса), в противном случае оно исчезнет (остановите отслеживание сеанса). Вы можете создать класс Timer в MyAppContext, чтобы периодически проверять значение isAppRunning, поэтому это будет:

public class MyAppContext extends Application {

   public boolean isAppRunning = true;
   public final int timerRate = 500;    // Execute timer task every 500mS

   public void setIsAppRunning(boolean v){
      isAppRunning = v;
   }

   public boolean isAppRunning(){
      return isAppRunning;
   }

   @Override
   public void onCreate() {
      super.onCreate();
      Timer mTimer = new Timer();

      mTimer.scheduleAtFixedRate(new TimerTask() {
         @Override
         public void run() {
            if(isAppRunning) startSesionTracking();
            else stopSesionTracking();
         }
      }, 0, REFRESH_TIME);
   }

   private void startSesionTracking () { ... };
   private void stopSesionTracking () { ... };

}

Вы должны изменить timerRate в соответствии с точностью, которую вы хотите получить при отслеживании сеанса.

Ответ 2

Расширьте все свои действия из BaseActivity, как показано ниже. Это лучший вариант для вас, так как onPause и методы onResume гарантированно будут вызываться всякий раз, когда ваши действия отображаются или исчезают с экрана телефона.

class BaseActivity extends Activity {


    @Override
    protected void onResume() {
        super.onResume();
        // Start Logging
    }

    @Override
    protected void onPause() {
        super.onPause();
        // End Logging
    }
}

Ответ 3

Вам нужно посмотреть в Activity lifecycles на Android.

Что вам нужно - onPause - см. документацию здесь

Я бы также упомянул, что onPause запускается даже при переключении между несколькими действиями, поэтому вам нужно будет отслеживать, когда он приостанавливается, чтобы перейти на другой экран.

Ответ 4

1.Создайте класс с именем AppLifecycleTracker и вставьте его.

private class AppLifecycleTracker implements ActivityLifecycleCallbacks {
            private int numStarted = 0;
            private String TAG = "AppLifecycleTracker";


            private int numOfCreated = 0;

            @Override`enter code here`
            public void onActivityCreated(Activity activity, Bundle bundle) {
                if (numOfCreated == 0) {
                    Log.d(TAG, "onActivityCreated: app started");
                }
                numOfCreated++;
                Log.d(TAG, "onActivityCreated: " + numOfCreated);
            }

            @Override
            public void onActivityStarted(Activity activity) {
                if (numStarted == 0) {
                    // app went to foreground
                    Log.d(TAG, "onActivityStarted: foreground");

                }
                numStarted++;


            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                numStarted--;
                if (numStarted == 0) {
                    // app went to background
                    Log.d(TAG, "onActivityStarted: background");

                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                numOfCreated--;
                Log.d(TAG, "onActivityDestroyed: " + numOfCreated);
            }
        }

* в onActivityCreate, если numOfCreated = 0, вы можете сказать, что приложение запустилось. * в onActivityDestroyed, если numOfCreated = 0, вы можете сказать, что приложение закрыто.

  1. Создайте расширяющее класс приложение, в onCreate, добавьте эту строку

    registerActivityLifecycleCallbacks (новый AppLifecycleTracker());

  2. установить имя приложения как класс приложения в manifest.xml

Вот оно. Вы хорошо пойдете.