2011-12-22 15 views
2

我使用LocationManager獲得一個位置修復:如何從LocationManager獲取單個位置修復程序,並且超時?

public class MyActivity extends Activity { 
    private LocationManager lm; 
    private ProgressDialog myDialog; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     LocationListener ll = new MyLocationListener(); 
     lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 1, ll); 
     myDialog = ProgressDialog.show(this, null , "Determining Your Location", true); 
    } 

    class MyLocationListener implements LocationListener { 
     public void onLocationChanged(Location location) { 
      if (location != null) { 
       ... 

       lm.removeUpdates(this); 
       myDialog.dismiss(); 
      } 
     } 
    } 
} 

由於這代表聆聽位置可能永遠持續下去,如果位置鎖定無法找到。我想通過在60秒之後停止監聽位置並向用戶顯示錯誤以表明他們的位置不能被確定來爲我的代碼添加一些健壯性。

我該怎麼做?

回答

-1

您可以使用Timer和TimerTask爲好。當您創建處理程序以利用postDelayed時,應該小心內存泄漏,因爲處理程序在它們完成後仍會引用您的「活動」或「服務」事件。 PostDelayed將進入主線程中的消息隊列。因此,請將您的處理程序設置爲靜態或使用弱引用。

您需要考慮以下代碼以避免內存泄漏。

public class MyService extends Service { 

    private static class MyHandler extends Handler { 
     WeakReference<MyService> ref; 

     public MyHandler(MyService r) { 
     ref = = new WeakReference<MyService>(r); 
     } 

     public void handleMessage(Message msg) { 

     MyService service = ref.get(); 
     if (servic==null) { 
      return; 
     } 

     //Do something here 
    } 

    } 

} 
2

你既可以用戶HandlerTimerAlarmManager致電LocationManager.removeUpdates停止監聽實行超時。

A Timer創建一個新的線程,這可能是矯枉過正。 AlarmManager的文檔建議「(f)或正常的定時操作(滴答,超時等)使用Handler更容易和更高效」。 Handler的文檔描述了Handler的主要用途之一是「將日程安排消息和可運行的程序作爲(某些)特定的時間點執行」。

所有的跡象都指出Handler是實現超時的最合適的方法。

public class MyActivity extends Activity implements LocationListener { 
    private final int TIMEOUT = 60000; 

    private LocationManager myLocationManager; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
     myLocationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER, 
      this, null); 

     Runnable myRunnable = new Runnable() { 
      public void run() { 
       myLocationManager.removeUpdates(QualityCheckActivity.this); 
       // other timeout error code 
      } 
     }; 

     Handler myHandler = new Handler(); 
     myHandler.postDelayed(myRunnable, TIMEOUT); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     // location fixed code 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { } 

    @Override 
    public void onProviderEnabled(String provider) { } 

    @Override 
    public void onProviderDisabled(String provider) { } 
} 

NOTES:

TIMEOUT是,當然,以毫秒爲單位的超時長度。在這種情況下60,000毫秒或60秒。

我已選擇在MyActivity本身上實現LocationListener接口,以便LocationListenerRunnable內更易於訪問。

而不是致電LocationManager.requestLocationUpdates:我正在使用LocationManager.requestSingleUpdate這將只提供一個位置修復程序。

我故意沒有執行Activity.onPauseActivity.onResume。如果活動暫停,位置監聽和超時將繼續。

相關問題