Android - вызов системной службы через фиксированные промежутки времени из другой службы

Как следует из вопроса, мне интересно, как я мог написать поток, который вызывал бы системную службу, а затем ждал определенное время, прежде чем вызывать функцию указанной системной службы, которая вызывает onReceive из зарегистрированного BroadcastReceiver.

Другими словами, я пытаюсь вызвать службу сканирования Wi-Fi (регистрируя BroadcastReceiver с IntentFilters) в своей пользовательской службе, чтобы получить текущий доступный SSID. Я знаю, что я буду делать с полученными данными, что не имеет отношения к этому вопросу. Однако мне нужно будет подождать некоторое время, прежде чем снова вызвать startScan в пределах onReceive, и именно здесь я пытаюсь определить наилучший план действий.

Мне удалось попробовать вызвать сканер Wi-Fi таким образом в моем потоке:

    private Object _lock = new Object();

    private final long SLEEP_TIME = 15000; //Scan every 15 secs
    private final long WIFI_SCAN_TIMEOUT = 60000; //One minute timeout for getting called back, otherwise, initiate a new scan.

   @Override
    public void run() {
        while(running){
            //Start a new scan;
            wifiSearchComplete = false;
            _wifiMan.startScan();
            while(!wifiSearchComplete){
                synchronized(_lock){
                    try{
                        _lock.wait(WIFI_SCAN_TIMEOUT);
                    } catch (InterruptedException ie){
                         Log.d(TAG, TAG+".run() caught " + ie.getMessage() +" when trying to sleep for " + (WIFI_SCAN_TIMEOUT/1000) +"secs.");
                         Thread.currentThread().interrupt();
                    }
                }
                if(!wifiSearchComplete){
                    synchronized(_lock){
                        //Try scanning again since we didn't get called back at all;
                        _lock.notify();
                    }
                }
            }
        }
    }

    public boolean isRunning(){
        return running;
    }

    public void stop(){
        synchronized(_lock){
            running = false;
            //unregister receivers and cleanup
            _lock.notify();
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        synchronized(_lock){
               wifiSearchComplete = true;
               //iterate through our SSID's
                try{
                    _lock.wait(SLEEP_TIME);
                } catch (InterruptedException ie){
                     Log.d(TAG, TAG+".onReceive() caught " + ie.getMessage() +" when trying to sleep for " + (SLEEP_TIME/1000) +"secs.");
                     Thread.currentThread().interrupt();
                }
                _lock.notify();
            }
    }

Однако, несмотря на то, что он ждет каждые 15 секунд перед повторным сканированием, при попытке выйти из моей тестовой активности (вызов onDestroy) он блокирует основной поток на время сна, прежде чем отвязать службу. Другими словами, является ли это подходящим способом попытаться выполнить то, что я хочу сделать, без блокировки, или мне нужно просто создать BroadcastReceiver и вызвать Thread.sleep в конце onReceive перед запуском нового сканирования?


person Diego Tori    schedule 15.04.2011    source источник


Ответы (1)


Вы должны реализовать IntentService. В вашей реализации переопределите onHandleIntent() для сканирования WiFi.

Затем используйте AlarmManager, чтобы запланировать отправку Intent в ваш IntentService с некоторым интервалом. Придумайте собственное имя действия: «diago.intent.scan_wifi» или что-то в этом роде. Если вы используете один из «неточных повторяющихся интервалов» (например, 15 минут), ОС Android будет планировать все остальные службы одновременно, чтобы свести к минимуму количество раз, когда телефон должен выходить из спящего режима.

Наконец, реализуйте BroadcastReceiver для ответа на ACTION_BOOT_COMPLETED и вызовите свой код для планирования AlarmManager. Это запустит вашу службу при загрузке.

Таким образом, когда AlarmManager отправит намерение, ваша служба будет загружена, выполнит сканирование и затем завершит работу.

person pzulw    schedule 15.04.2011
comment
Я хочу, чтобы моя служба работала только тогда, когда к ней привязаны действия приложения, а это означает, что моя домашняя активность будет последней, которая отключится от нее, тем самым отключив службу. Указанные вами интервалы слишком велики, идея состоит в том, чтобы отправить эти данные обратно в ограниченную активность и проверить наличие дополнительных SSID короткими волнами, а не через панель уведомлений. - person Diego Tori; 16.04.2011