2010-06-25 29 views
9

Kiểm tra ứng dụng của tôi tại một thời điểm cụ thể cho dù người dùng có ở một vị trí cụ thể hay không. Tôi sử dụng người quản lý báo động để bắt đầu một dịch vụ mà làm cho cuộc gọi này:Android - Nhận được vị trí hiện tại một cách đáng tin cậy

locationManager.requestLocationUpdates(bestProvider, 0, 0, listener); 

Và cũng kiểm tra:

locationManager.getLastKnownLocation(bestProvider); 

Nhưng tôi đang gặp vấn đề khi chạy trên một thiết bị thực sự. Đối với một điều, getLastKnownLocation rất có thể là nơi cuối cùng GPS là trên, mà có thể là bất cứ nơi nào (ví dụ, nó có thể là dặm từ vị trí hiện tại của người dùng). Vì vậy, tôi sẽ chỉ đợi requestLocationUpdates cuộc gọi lại và nếu họ không ở đó trong vòng hai phút, hãy xóa người nghe và bỏ cuộc, phải không?

Sai, vì nếu vị trí của người dùng đã ổn định (tức là họ đã sử dụng GPS gần đây và chưa di chuyển) thì người nghe của tôi sẽ không bao giờ được gọi vì vị trí không thay đổi. Tuy nhiên, GPS sẽ chạy cho đến khi người nghe của tôi bị xóa, tháo pin ...

Cách đúng để nhận vị trí hiện tại mà không nhầm vị trí cũ cho vị trí hiện tại là gì? Tôi không quan tâm chờ đợi một vài phút.

EDIT: Có thể tôi sai về người nghe không được gọi, có thể mất nhiều thời gian hơn tôi nghĩ ... Khó nói. Tôi vẫn đánh giá cao câu trả lời dứt khoát.

Trả lời

5

Mã này có thể được một cái gì đó như thế:

public class MyLocation { 
    Timer timer1; 
    LocationManager lm; 

    public boolean getLocation(Context context) 
    { 
     lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); 
     lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps); 
     timer1=new Timer(); 
     timer1.schedule(new GetLastLocation(), 20000); 
     return true; 
    } 

    LocationListener locationListenerGps = new LocationListener() { 
     public void onLocationChanged(Location location) { 
      timer1.cancel(); 
      lm.removeUpdates(this); 
      //use location as it is the latest value 
     } 
     public void onProviderDisabled(String provider) {} 
     public void onProviderEnabled(String provider) {} 
     public void onStatusChanged(String provider, int status, Bundle extras) {} 
    }; 

    class GetLastLocation extends TimerTask { 
     @Override 
     public void run() { 
      lm.removeUpdates(locationListenerGps); 
      Location location=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      //use location as we have not received the new value from listener 
     } 
    } 
} 

Chúng tôi bắt đầu nghe và chờ đợi bản cập nhật cho một thời gian (20 giây trong ví dụ của tôi). Nếu chúng tôi nhận được cập nhật trong thời gian này, chúng tôi sử dụng nó. Nếu chúng tôi không nhận được bản cập nhật trong thời gian này, chúng tôi sử dụng giá trị getLastKnownLocation và dừng trình nghe.

Bạn có thể xem mã hoàn chỉnh của tôi ở đây What is the simplest and most robust way to get the user's current location on Android?

EDIT (bằng cách hỏi): Đây là hầu hết các câu trả lời, nhưng giải pháp cuối cùng của tôi sử dụng một Handler thay vì một Timer.

+0

Bạn có thể cung cấp một số mã ví dụ không? ví dụ: bạn sẽ đợi 2 phút hoặc như thế nào nếu người nghe vị trí không được gọi? – noah

+0

Đoạn mã được thêm – Fedor

4

Nếu vị trí của người dùng đã ổn định thì getLastKnownLocation sẽ trả lại vị trí hiện tại. Trước tiên tôi muốn gọi số getLastKnownLocation, hãy xem dấu thời gian (so sánh Location.getElapsedRealTimeNanos() với SystemClock.elapsedRealTimeNanos()) rồi đăng ký người nghe nếu sửa chữa quá cũ.

+0

Cảm ơn, tôi không biết về getTime(). Vấn đề với điều này là, phải mất bao nhiêu thời gian trước khi nhà cung cấp vị trí xem xét quá cũ? Làm thế nào tôi có thể đảm bảo rằng người nghe của tôi sẽ được gọi nếu tôi không sử dụng địa điểm đó? – noah

+1

Các nhà cung cấp vị trí không xem xét nó quá cũ, nó không bao giờ loại bỏ nó (theo như tôi biết). Bạn phải quyết định khi nào bạn xem xét bản sửa lỗi quá cũ và yêu cầu cập nhật nếu cần. Sau đó, bạn vẫn có thể sử dụng vị trí cũ nếu không có cập nhật trong một thời gian nhất định. – cristis

+2

Có một vấn đề nhỏ ở đây: API không xác định nguồn gốc của dấu thời gian được trả về bởi Location.getTime(). Đối với GPS, có vẻ như là thời gian vệ tinh. Đối với nhà cung cấp mạng, có vẻ như là thời gian thiết bị cục bộ. Điều đó khiến việc xác định độ tuổi của một vị trí khó xác định một cách đáng tin cậy - được coi là khả năng đồng hồ của người dùng có thể không chính xác hoặc múi giờ có thể bị định cấu hình sai. – sstn

Các vấn đề liên quan