如何从LocationManager获取单个位置修复,超时?

时间:2011-12-22 19:38:30

标签: android 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秒后停止监听位置来为我的代码添加一些健壮性,并向用户显示错误,说明他们的位置无法确定。

我该怎么做?

3 个答案:

答案 0 :(得分:2)

您可以使用HandlerTimerAlarmManager来通过调用LocationManager.removeUpdates来停止收听来实现超时。

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) { }
}

注意:

TIMEOUT当然是超时长度(以毫秒为单位)。在这种情况下为60,000毫秒,或60秒。

我选择在LocationListener本身上实施MyActivity界面,以便LocationListener更容易访问Runnable

而不是调用LocationManager.requestLocationUpdates:我正在使用LocationManager.requestSingleUpdate,它只提供一个位置修复。

我故意没有实施Activity.onPauseActivity.onResume。如果暂停活动,则位置侦听和超时都将继续。

答案 1 :(得分:1)

一种方法是使用Handler并在60秒后使用postDelayed来停止听众。

Handler postDelayed

答案 2 :(得分:-1)

您也可以使用Timer和TimerTask。当您创建使用postDelayed的处理程序时,您应该注意内存泄漏,因为处理程序在完成后仍会引用您的Activity或Service事件。 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
     }

   }

}