Определите, если приложение на переднем плане - это осуждается?

Есть много причин, почему нужно определить, находится ли приложение на переднем плане. например - в качестве триггера для push-уведомлений GCM/C2DM - у многих приложений будет веская причина для реализации другого поведения, когда приложение находится на переднем плане и на заднем плане. Другая причина может быть - отключение сервисов, потребляющих драгоценные ресурсы, таких как запросы серверов, например, в фоновом режиме.

Просто чтобы быть ясно: определение (как я вижу это) для фонового приложения:
приложение, которое ни одна из его деятельности не вызывается onStart() метод, и еще не вызывать onStop() метод. это потому, что активность видна пользователю в ее жизненном цикле только в это время.

С другой стороны -

  • Похоже, Google не хочет, чтобы приложение реагировало на кнопку "Домой" (это не является частью API)

  • реагируя на onBackPressed() на активность "root / main" как индикатор ухода Activity конечно, не очень хорошая идея (потому что многие пользователи используют кнопку "домой", а не кнопку "Назад")

  • в API нет метода, позволяющего определить, находится ли приложение на переднем плане (согласно моему определению..)

если я не пропустил что-то в API, и это действительно так - почему нет такого, почему легко определить, является ли приложение передним планом или нет????!!!!

что я знаю, что могу сделать, чтобы определить, является ли приложение передним планом, описано в этой теме - Как определить, когда приложение Android переходит в фоновый режим и возвращается на передний план

но, как говорит @Emil, - это требует специального разрешения или какой-то хитрой логики, которую очень быстро становится проблематично поддерживать, и пахнет как плохой подход (хотя это то, чем я сейчас занимаюсь, потому что у меня нет лучшей идеи...)

мои вопросы в основном таковы:

  • Нет ли такого метода API по уважительной причине?

  • Учитывает ли приложение приоритет или плохой подход?

  • Есть ли другой способ узнать, является ли приложение на переднем плане или нет?

3 ответа

Решение

учитывает ли приложение на переднем плане или нет, это плохой подход?

Принятие во внимание переднего плана против фона разумно.

Есть ли другой способ узнать, является ли приложение на переднем плане или нет?

Вы можете грубо разделить сценарии для этого на две группы:

  1. Случаи, когда вы хотите выполнить действие сразу после изменения статуса переднего плана / фона

  2. Случаи, когда происходит другое событие (AlarmManager тревога, входящая системная трансляция и т. д.), и в этот момент вы хотите предпринять различные действия в зависимости от того, находитесь ли вы на переднем плане или нет.

В первом случае, onUserLeaveHint() ваш самый надежный простой вариант. Я не могу гарантировать, что он будет охватывать все случаи, но он должен обрабатывать сценарий HOME, например. Вы также можете вести подсчет количества запущенных операций в статическом элементе данных и пытаться использовать его вместо этого.

В последнем случае заказная трансляция может быть полезна.

Новые компоненты архитектуры Android позволяют легко узнать, находится ли ваше приложение на переднем плане или на заднем плане.

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

Например:

Добавьте этот код, чтобы зарегистрироваться в качестве наблюдателя жизненного цикла

ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleListener)

И этот код для того, чтобы получить соответствующие обратные вызовы

@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onApplicationOnStartEvent() {

}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onApplicationOnStopEvent() {

}

Не забудьте убрать наблюдателя, если он вам не нужен

ProcessLifecycleOwner.get().getLifecycle().removeObserver(lifecycleListener);

Больше информации и примеров можно найти в этой превосходной статье:

https://proandroiddev.com/detecting-when-an-android-app-backgrounds-in-2018-4b5a94977d5c

Если вам необходимо знать, находится ли приложение в фоновом режиме или на переднем плане от службы, работающей в фоновом режиме (в противном случае это не имеет смысла), то вы можете просто использовать привязку, то есть - привязывать к ней все свои действия на Resume. и отмените привязку ко всем действиям на паузе. тогда в вашем сервисе вы можете управлять не только видимостью вашего приложения для пользователя, но и тем, какие действия открыты в любое время. он также защищен от утечек и более стабилен, чем статическая переменная (которую можно очистить при необходимости), так как вы используете API Android и полагаетесь на правильность самого кода ОС Android.

Я была такая же проблема. Я хочу отображать push-уведомления, когда моя активность не в режиме переднего плана. Пожалуйста, пройдите по следующему коду, и вы получите ответ.

    Context ctx = context.getApplicationContext();

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

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

    PackageManager pm = this.getPackageManager();

    try {
        /**
         * take fore ground activity name
         */
        ComponentName componentInfo = taskInfo.get(0).topActivity;
        if (printLog == true) {
            Log.d("Home", "CURRENT Activity ::"
                    + taskInfo.get(0).topActivity.getClassName());
            Log.d("Home", "Number Of Activities : "
                    + taskInfo.get(0).numRunning);
            Log.d("Home",
                    "Componenet Info : " + componentInfo.getPackageName());
            Log.d("Home",
                    "Componenet Info : " + componentInfo.getClassName());
        }
        /**
         * All activities name of a package to compare with fore ground
         * activity. if match found, no notification displayed.
         */
        PackageInfo info = pm.getPackageInfo(
                "<PackageName>",
                PackageManager.GET_ACTIVITIES);
        ActivityInfo[] list = info.activities;

        for (int i = 0; i < list.length; i++) {
              Log.d("TAG","Activity : "+list[i].name);
        }

    } catch (NameNotFoundException e) {
        e.printStackTrace();
    }

Чтобы использовать это, вы должны получить разрешение в вашем manifest файл.

использует разрешение android:name="android.permission.GET_TASKS"

Извините, если я не могу получить ваш вопрос.

Другие вопросы по тегам