Android - Вызов системного сервиса через определенные промежутки времени из другого сервиса. - PullRequest
0 голосов
/ 16 апреля 2011

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

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

Мне удалось попытаться позвонитьwifi scanner в моей теме:

    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 перед вызовом, чтобы начать новое сканирование

1 Ответ

2 голосов
/ 16 апреля 2011

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

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

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

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

...