Android: "Уровень приложения" Пауза и возобновление

Я пытаюсь заставить Application Pause и возобновить аналогично активности onPause и onResume. Я знаю, что нет API, который имеет эту функциональность.

Я стараюсь следить за этим сообщением: http://curioustechizen.blogspot.com/2012/12/android-application-level-pause-and.html

Но мне пока не повезло.

Кто-нибудь смог достичь этого? Какую парадигму вы использовали?

Сообщите мне, если вам понадобится, чтобы вставить код в этот вопрос. Спасибо за помощь

Ответ 1

Другим решением проблемы было бы просто отслеживать количество вызовов onStart() и onStop() от каждого действия. Пример:

Сначала создайте класс для хранения счетчиков:

public class ActiveActivitiesTracker {
    private static int sActiveActivities = 0;

    public static void activityStarted()
    {
        if( sActiveActivities == 0 )
        {
            // TODO: Here is presumably "application level" resume
        }
        sActiveActivities++;
    }

    public static void activityStopped()
    {
        sActiveActivities--;
        if( sActiveActivities == 0 )
        {
            // TODO: Here is presumably "application level" pause
        }
    }
}

Затем в каждом действии просто вызовите методы activityStarted() и activityStopped():

@Override
public void onStart() {
    super.onStart();
    ActiveActivitiesTracker.activityStarted();
}

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

Ответ 2

У меня была та же проблема. Моя цель состояла в том, чтобы заблокировать приложение, если пользователь отказался от него. Простая цель, о которой я думал, будет легко реализовать. Но все решения, которые я нашел, были сложными. Поэтому я пришел к простому решению: блокировка времени.

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

  • Запуск обратного отсчета для блокировки приложения в onPause
  • Остановить обратный отсчет в onResume
  • Если onResume не вызывается во времени, переключитесь на заблокированный

Для этого я создал небольшой класс:

public class ApplicationLock {

private static final String TAG = ApplicationLock.class.getSimpleName();
private static final int LOCK_TIME = 1000; //lock after a second
private static boolean lock = true; //default is locked
private static Handler handler = new Handler();
private static Runnable runnable = new Runnable() {
    @Override
    public void run() {
        lock = true;
        Log.i("ActivityTracker", "App locked");
    }
};

public static boolean activityStarted()
{
    handler.removeCallbacks(runnable);
    if(lock)
    {
        Log.i(TAG, "App resumed - LOCKED");
        return true;
    }else{
        Log.i(TAG, "App resumed - NOT LOCKED");
        return false;
    }
}

public static void activityStopped()
{
    handler.postDelayed(runnable, LOCK_TIME);
    Log.i(TAG, "App paused - Starting countdown");

}

Просто вызовите activityStopped() в своих действиях onPause() и activityStarted() в onResume(). Проверьте результат activityStarted(). Если он вернет true, заблокируйте приложение. Если ориентация приложения изменилась, onResume будет вызываться очень быстро после onPause, поэтому приложение не будет блокироваться.

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

Ответ 3

Я сделал что-то очень похожее на это в приложении, которое использовало сервис, который предоставлял функции GPS несколькими действиями. Идея заключалась в том, чтобы иметь только службу там, когда один из видов деятельности, которые ее использовали, виден, а не там, когда нет видимых. В вашем случае каждое действие будет подключаться к службе, и вы узнаете, когда все приложение было приостановлено или возобновлено, подключившись к методам onCreate() и onDestroy().

Вот пример урезанного:

Необходимые компоненты (возможно, они могут быть помещены в класс утилиты, если вы хотите их повторно использовать, или я просто использовал их для каждого класса активности):

private boolean mAppActiveServiceBound = false;
private AppActiveService mAppActiveService = null;
private ServiceConnection mAppActiveConnection = new ServiceConnection() {
    public void onServiceConnected( ComponentName className, IBinder service ) {
        mAppActiveService = ( (AppActiveService.AppActiveBinder) service ).getService();
    }
    public void onServiceDisconnected( ComponentName className ) {
        mAppActiveService = null;
    }
};

Затем в ваших методах onStart() и onStop() для каждого действия:

@Override
public void onStart() {
    super.onStart();
    mAppActiveServiceBound = bindService( new Intent( this, AppActiveService.class ), mAppActiveConnection, Context.BIND_AUTO_CREATE );
}

@Override
public void onStop() {
    super.onStop();
    if( mAppActiveServiceBound ) {
        unbindService( mAppActiveConnection );
        mAppActiveServiceBound = false;
    }
}

И, наконец, сама служба:

public class  AppActiveService extends Service {
    // Receives interactions from clients:
    private final IBinder mBinder = new AppActiveBinder();

    /**
     * Provides a handle to the bound service.
     */
    public class  AppActiveBinder extends Binder {
        AppActiveService getService() {
            return AppActiveService.this;
        }
    }

    @Override
    public void onCreate(){
        // TODO: Here is presumably "application level" resume
    }

    @Override
    public void onDestroy(){
        // TODO: Here is presumably "application level" pause
    }
}