Обнаружение Android-приложения собирается в фоновом режиме

Мне нужно отключить Bluetooth, когда мое приложение "переходит в фоновый режим"/"становится неактивным".

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

То, что мне нужно, это своего рода "onPause()" моего приложения, а не одного действия.

Я думаю, что ничего подобного не существует, так есть ли какое-либо предпочтительное решение?

7 ответов

Извлеките эту зависимость из файла build.gradle:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

Затем в вашем классе приложения используйте это:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

Обновите файл AndroidManifest.xml:

<application
    android:name=".MyApplication"
    ....>
</application>

ОБНОВЛЕНИЕ: Осторожно, согласно комментариям, это не работает во всех случаях!!!

Решения, перечисленные здесь на SO, кажутся мне слишком сложными. Я пришел, используя это:

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

public class SharedData {
    static int runningActivities = 0;
}

В каждом действии переопределите эти два метода.

public void onStart() {
    super.onStart();
    if (SharedData.runningActivities == 0) {
        // app enters foreground
    }
    SharedData.runningActivities++;
}

public void onStop() {
    super.onStop();
    SharedData.runningActivities--;
    if (SharedData.runningActivities == 0) {
        // app goes to background
    }
}

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

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

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if(level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
        //called when app goes to background
}

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

private boolean isApplicationBroughtToBackground() {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
        ComponentName topActivity = tasks.get(0).topActivity;
        if (!topActivity.getPackageName().equals(context.getPackageName())) {
            return true;
        }
    }

    return false;
}

Для не одного приложения Activity, я бы порекомендовал, чтобы каждое действие осуществляло контроль видимости на основе времени. Запускайте для каждого onPause() синхронизированную проверку состояния, а также отменяйте этот таймер для каждого метода onResume().

Вот пример

    @Override
protected void onPause() {
    TimerTask backgroundCheck = new TimerTask() {

        @Override
        public void run() {
            ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
            if (!tasks.isEmpty()) {
                ComponentName topActivity = tasks.get(0).topActivity;
                if (!topActivity.getPackageName().equals(getApplicationContext().getPackageName())) {
                    // APP in background, do something
                }
            }

            // APP in foreground, do something else
        }
    };

    Timer isBackgroundChecker = new Timer();
    isBackgroundChecker.schedule(backgroundCheck, 1000, 1000);

    super.onPause();
}

После этого не забудьте отменить Timer isBackgroundChecker = new Timer();

Не рекомендуется использовать RunningTaskInfo потому что его "метод предназначен только для отладки и представления пользовательских интерфейсов управления задачами". хорошо, если вы разрабатываете приложение для ICS и выше, я нашел эту ссылку очень полезной!

http://vardhan-justlikethat.blogspot.in/2013/05/android-solution-to-detect-when-android.html

Вы можете реализовать onPause() для каждого действия, которое у вас есть, но я не думаю, что необходимо самостоятельно отключать Bluetooth, некоторые пользователи могут использовать Bluetooth по какой-то другой причине или хотят отключить его самостоятельно (вот что Я делаю)

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