Как предотвратить onPause() при нажатии кнопки «Домой»?

Я работаю над приложением libGDX, которое включает таймер. Мне нужно, чтобы таймер работал даже при нажатии кнопки домой, и даже при выключении экрана нажатием кнопки вкл.выкл.

Для этого я подумал о том, чтобы приложение не переходило в состояние паузы. В AndroidLauncher.java я добавляю следующие строки кода:

@Override
  public void onPause() {
        onResume();
  }

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

Вот логарифм приложения после нажатия кнопки «Домой» и возврата к приложению:

01-26 18:17:25.125: I/AndroidInput(2753): настройка прослушивателя датчиков

01-26 18:17:25.126: I/AndroidGraphics(2753): возобновлено

01-26 18:17:25.191: W/IInputConnectionWrapper(2753): showStatusIcon для неактивного InputConnection

01-26 18:17:28.899: I/AndroidInput(2753): датчик

01-26 18:17:28.919: I/AndroidGraphics(2753): возобновлено

Как видите, когда приложение запущено, если я нажимаю кнопку «Домой», приложение возобновляет работу, не переходя в состояние паузы, а когда я возвращаюсь к приложению, оно снова возобновляется. Но таймер остановился...

Почему таймер останавливается, когда приложение никогда не находится в состоянии паузы? И, наконец, как я могу запустить таймер после нажатия кнопки «Домой»?

Спасибо


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

Вот стратегия:

  • На моем GameScreen у меня есть таймер, где я могу ввести количество секунд,
  • затем я использую задачу обратного отсчета до 0.
  • Поскольку я работаю над проектом libGDX, я использую интерфейс для передачи текущего количества секунд в AndroidLauncher, когда игра переходит в состояние паузы.
  • Этот интерфейс также запускает службу, которая поддерживает обратный отсчет с тем же таймером и задачей, и каждую секунду печатает текущее количество секунд в консоли.

Код:

Таймер в GameScreen.java:

timer = new Timer();
timer.scheduleTask(new Task(){
        public void run() {
            timerSeconds--;
        }
    }, 1,1);

Интерфейс ActionResolver.java:

public interface ActionResolver {
    public void backgroundTimer(int a);
}

ActionResolver вызывается в основном действии MyGdxGame.java:

@Override
public void pause() {
    super.pause();
    actionResolver.backgroundTimer(GameScreen.timerSeconds);
}

Метод backgroundTimer определен в AndroidLauncher:

@Override
public void backgroundTimer(int a) {
    aa = a;
    
    Intent intentTimer = new Intent(AndroidLauncher.this, IntentServiceTimer.class);
    intentTimer.putExtra(TIMER, aa);
    startService(intentTimer);
}

Затем я создал класс намеренияServiceTimer:

public class IntentServiceTimer extends IntentService{
private final static String TAG = "IntentServiceExample";
int a;

public IntentServiceTimer(){
    super(TAG);
}

@Override
protected void onHandleIntent(final Intent intent) {
    Log.d(TAG, "When the game went on pause, the number of remaining seconds was : " + intent.getIntExtra(AndroidLauncher.TIMER, -1));
    
    a = intent.getIntExtra(AndroidLauncher.TIMER, -1);
    Timer timer = new Timer();
    timer.scheduleTask(new Task(){
        public void run() {
           a--;
           Log.d(TAG, "Seconds remaining : " + a);
        }
    }, 1,1);        
}
}

В AndroidManifest.xml я объявил службу:

<service android:name="IntentServiceTimer"/>

Результаты:

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

Log.d(TAG, "When the game went on pause, the number of remaining seconds was : " + intent.getIntExtra(AndroidLauncher.TIMER, -1));

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

Осталось секунд: 27

Осталось секунд: 26

Осталось секунд: 25

Осталось секунд: 24

Осталось секунд: 23

Итак, у меня есть это странное поведение службы:

  • вывести 1-е сообщение, когда ожидается (когда игра переходит в состояние паузы)
  • Обратный отсчет, кажется, работает в фоновом режиме
  • Результат обратного отсчета печатается только при возобновлении

Вы имеете представление об этой проблеме? Я еще не проверял аварийный менеджер, так как мне нужно, чтобы в фоновом режиме работал более сложный процесс, в будущем службы кажутся тем, что мне нужно.


person vdlmrc    schedule 26.01.2015    source источник
comment
потому что вызов onResume не заставляет ваше приложение не спать. Если ваша активность находится в фоновом режиме, она приостанавливается. Что вам нужно сделать, так это сохранить состояние вашего таймера в onPause вместе со временем, чтобы вы могли правильно восстановить его, когда пользователь вернется в приложение.   -  person njzk2    schedule 27.01.2015
comment
Если вам нужно, чтобы таймер срабатывал и тогда, когда ваша деятельность не активна, вам нужен либо менеджер аварийных сигналов, либо служба.   -  person njzk2    schedule 27.01.2015
comment
Для любых задач, связанных со временем, вы должны использовать AlarmManager   -  person tachyonflux    schedule 27.01.2015
comment
Спасибо за ваши Коментарии. Я проверяю службы, которые кажутся решением, но мне все еще нужна небольшая помощь, чтобы служба работала правильно. Я обновил свой вопрос новым кодом. Есть идеи ? Спасибо !   -  person vdlmrc    schedule 27.01.2015


Ответы (2)


Для решения этой проблемы следует использовать службу: Services.

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

    protected void onUserLeaveHint() {
        super.onUserLeaveHint();
    }
person JavierSegoviaCordoba    schedule 26.01.2015
comment
Спасибо за ваш ответ ! Сервисы вроде бы то, что мне нужно, но у меня странное поведение моего сервиса. Я обновил свой первоначальный вопрос новым кодом. Если у вас есть представление о мелочах, которых не хватает в моем коде для правильной работы, было бы здорово! Спасибо ! - person vdlmrc; 27.01.2015

ХОРОШО ! Итак, после того, как я весь день злился на эту проблему, я наконец нашел (очень простое) решение:

В редактировании моего первоначального вопроса я начал работать с сервисами, но у меня было очень странное поведение сервиса. Моя проблема возникла из-за того, что в моем классе IntentService я использовал метод Timer() и Task() из пакета libgdx.

Я просто заменил эти два класса эквивалентными методами Timer() и TimerTask() из пакета java.util, и все работает без сбоев!

Итак, теперь мой IntentServiceTimer выглядит так:

import java.util.Timer;
import java.util.TimerTask;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class IntentServiceTimer extends IntentService{
private final static String TAG = "IntentServiceExample";
int a;

public IntentServiceTimer(){
    super(TAG);
}

@Override
protected void onHandleIntent(final Intent intent) {
    Log.d(TAG, "When the game went on pause, the number of remaining seconds was : " + intent.getIntExtra(AndroidLauncher.TIMER, -1));

    a = intent.getIntExtra(AndroidLauncher.TIMER, -1);
    Timer timer = new Timer();
    timer.schedule(new TimerTask(){
        public void run() {
           a--;
           Log.d(TAG, "Seconds remaining : " + a);
        }
    }, 1,1);        
}
}
person vdlmrc    schedule 28.01.2015