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

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

  1. основная деятельность:
    AlarmManager в onCreate()
  2. alarm_receiver:
    start_service приобретает частичный_wl для службы
  3. оказание услуг:
    получить сетевые данные, используя StrictMode pop activity_2, если данные ожидаются
  4. activity_2:
    вибрационная кнопка для выхода(activity_2.this.finish())

Но в тестировании я обнаружил, что служба остановится (будет убита) через первые 30 минут. Кроме того, если я запускаю поток для работы в сети вместо использования StrictMode, он будет уничтожен через 5 минут после блокировки экрана.

Надеюсь, что кто-то может дать предложение для этого. Это действительно тревожит. Большое спасибо.

2 ответа

Я изменил несколько вещей, и теперь это работает хорошо.

1. Поскольку мой телефон 4.4.2(api=19), alarmmanager.setrepeating является неточным. Поэтому я перехожу к использованию.setExact (новый метод.set()) и перепланирую тревогу в конце AsyncTask(сеть) в Сервисе.

2. Сделайте экземпляр wakelock глобальным, получив его в AlarmReceiver и выпустив его в конце AsyncTask. Раньше я помещал.release() в onDestroy(), который снимает блокировку до того, как задача будет выполнена.

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

Общая служба не знает, что происходит с деятельностью. если вы хотите, чтобы начать периодически проверять мой сервис: https://bitbucket.org/kvrus/ocs-android/raw/036de7f0d3579b2a193bcb82309f7f82819508e6/app/src/main/java/koss/ru/oneclickrate/network/EcbEuropeService.java

/ ** * Периодически загружает обменные курсы из сети * Возвращает результаты в широковещательном сообщении. * Создано koss 19.02.16. * */ открытый класс EcbEuropeService расширяет сервис {

public static final String ECB_URL = "http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml";
public static final int UPDATE_PERIOD = 30000;
public static final int UPDATE_TICK = 1000;

public static final String NOTIFICATION = "koss.ru.oneclickrate.receiver";
public static final String EXTRA_CURRENCIES_MAP = "extra_currencies_map";

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    getUrlData();
    return Service.START_NOT_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

public Cubes getUrlData() {
    (new AsyncTask<Object, Object, Cubes>() {
        Map<CurrencyType, BigDecimal> result = new EnumMap<CurrencyType, BigDecimal>(CurrencyType.class);

        @Override
        protected Cubes doInBackground(Object... params) {
            Cubes cubes = new Cubes();
            InputStream is = null;
            HttpURLConnection urlConnection = null;
            try {
                URL url = new URL(ECB_URL);
                urlConnection = (HttpURLConnection) url.openConnection();
                is = urlConnection.getInputStream();
                cubes = EcbEuropeResponseParser.parse(is);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(urlConnection!=null) IOUtils.close(urlConnection);
                if(is!=null) IOUtils.closeQuietly(is);
                return cubes;
            }
        }

        @Override
        protected void onPostExecute(Cubes map) {
            super.onPostExecute(map);
            sendBroadcastMessage(map);
            startTimer();
        }
    }).execute();
    return null;
}

/**
 * Restarts timer
 * */
public void startTimer() {
    cdt.cancel();
    cdt.start();
}

CountDownTimer cdt = new CountDownTimer(UPDATE_PERIOD, UPDATE_TICK) {
    @Override
    public void onTick(long millisUntilFinished) {

    }

    public void onFinish() {
        getUrlData();
    }
};

private void sendBroadcastMessage(Cubes currenciesMap) {
    Intent intent = new Intent(NOTIFICATION);
    intent.putExtra(EXTRA_CURRENCIES_MAP, currenciesMap);
    sendBroadcast(intent);
}
Другие вопросы по тегам