0

正如問題所暗示的,我想知道如何編寫一個線程來調用系統服務,然後在調用所述系統服務的函數之前等待一段時間請從註冊的BroadcastReceiver回撥onReceiveAndroid - 從另一個服務以固定時間間隔調用系統服務

換句話說,我試圖在我的自定義服務中調用Wifi掃描服務(在中註冊),以便我可以獲得當前的SSID。我知道我最終會如何處理收到的數據,這與這個問題無關。但是,我需要等待一定的時間才能再次撥打startScan並在onReceive之內,那就是我想要確定最佳行動方案的地方。

我設法嘗試調用我的線程內,以這種方式在WiFi掃描:

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並在onReceive的末尾調用Thread.sleep

回答

2

您應該實施一個IntentService。在你的實現重寫onHandleIntent()來做WiFi掃描。

接下來,使用AlarmManager安排以一定的時間間隔向IntentService發送Intent。製作你自己的動作名稱:「diago.intent.scan_wifi」或類似的東西。如果您使用其中一個「不精確的重複間隔」(例如15分鐘),則Android操作系統將同時安排所有其他服務,以最大限度地減少手機必須從睡眠模式中喚醒的次數。

最後,實現BroadcastReceiver來響應ACTION_BOOT_COMPLETED並調用您的代碼來安排AlarmManager。這將啓動您的服務啓動。

這種方式當AlarmManager發送意圖時,您的服務將被加載,執行掃描,然後退出。

+0

我只希望我的服務在應用程序的活動綁定時運行,這意味着我的家庭活動將是最後一個從其解除綁定的活動,從而關閉服務。您指定的時間間隔太長,我們的想法是將數據發送回有界活動,並通過短波檢查更多SSID,而不是通過通知欄。 – 2011-04-15 21:45:25

+0

然後使用TimerTask – pzulw 2011-04-19 21:07:28