2013-03-09 24 views
10

Tôi đang nhận được vị trí đã biết cuối cùng của mình nhưng không được bao lâu kể từ khi vị trí của tôi được cập nhật lần cuối. Làm thế nào tôi có thể biết được nó đã kéo dài bao lâu kể từ khi vị trí được cập nhật lần cuối?Vị trí được biết cuối cùng được ghi lại trong bao lâu?

LocationManager locationManager 
         = (LocationManager) getSystemService(LOCATION_SERVICE); 
Criteria c = new Criteria(); 
    c.setAccuracy(Criteria.ACCURACY_FINE); 
    c.setAccuracy(Criteria.ACCURACY_COARSE); 
    c.setAltitudeRequired(false); 
    c.setBearingRequired(false); 
    c.setCostAllowed(true); 
    c.setPowerRequirement(Criteria.POWER_HIGH); 
String provider = locationManager.getBestProvider(c, true); 
Location location = locationManager.getLastKnownLocation(provider); 
+0

Cách đăng ký cập nhật vị trí và đo chênh lệch thời gian giữa các bản cập nhật đã nhận? Khi bạn nhận được một bản cập nhật vị trí, ví dụ Vị trí cho phép bạn lấy lại thời gian cập nhật thông qua getTime() (hãy cẩn thận, nó ở dạng UTC). – AgentKnopf

+0

['location.getTime();'] (http://developer.android.com/reference/android/location/Location.html#getTime%28%29) nói về ['getElapsedRealtimeNanos()'] (http: //developer.android.com/reference/android/location/Location.html#getElapsedRealtimeNanos%28%29) để tính tuổi sửa lỗi và so sánh Sửa địa điểm. [Ví dụ] (https://code.google.com/p/android-protips-location/source/browse/trunk/src/com/radioactiveyak/location_best_practices/utils/GingerbreadLastLocationFinder.java) tại [blog] (http : //android-developers.blogspot.com/2011/06/deep-dive-into-location.html) sử dụng 'getTime()'. – kush

+0

getElapsedRealtimeNanos() là cách tiếp cận được khuyến nghị trong tương lai, nhưng chỉ có sẵn trong API 17 (4.2) trở lên, vì vậy getTime thực sự là điều duy nhất để sử dụng kể từ thời điểm viết ... – JamesSugrue

Trả lời

19

lựa chọn tốt nhất cho cả trước và sau API 17:

public int age_minutes(Location last) { 
    return age_ms(last)/(60*1000); 
} 

public long age_ms(Location last) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) 
     return age_ms_api_17(last); 
    return age_ms_api_pre_17(last); 
} 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) 
private long age_ms_api_17(Location last) { 
    return (SystemClock.elapsedRealtimeNanos() - last 
      .getElapsedRealtimeNanos())/1000000; 
} 

private long age_ms_api_pre_17(Location last) { 
    return System.currentTimeMillis() - last.getTime(); 
} 

Các pre 17 không phải là rất chính xác, nhưng phải đủ để kiểm tra xem một vị trí là rất cũ.

này, tôi nên suy nghĩ, sẽ là OK:

if (age_minutes(lastLoc) < 5) { 
    // fix is under 5 mins old, we'll use it 

} else { 
    // older than 5 mins, we'll ignore it and wait for new one 

} 

Các trường hợp sử dụng thông thường cho logic này là khi các ứng dụng đã chỉ mới bắt đầu và chúng ta cần phải biết liệu chúng tôi phải chờ một vị trí mới hoặc có thể sử dụng tính năng mới nhất hiện tại trong khi chúng tôi chờ một vị trí mới.

+0

Tôi tin rằng giải pháp này có một lỗ hổng - hãy tưởng tượng nếu tôi có lastLocation được lưu trữ trong một số lưu trữ kiên trì. Giả sử tôi đã cập nhật vị trí cuối cùng 3 giờ kể từ lần khởi động lại điện thoại cuối cùng. Bản cập nhật vị trí này được lưu trữ trong bộ nhớ. Sau đó, tôi khởi động lại điện thoại và gọi "age_minutes (last)". Tôi sẽ nhận được SystemClock = ~ 1min và lastLocation = 3 giờ. "age_minutes" sẽ trả lại giá trị đúng mà không chính xác. – Michal

+0

@Michal Lỗ hổng đang nghĩ bạn tự lưu trữ vị trí cuối cùng. Luôn hỏi 'locationManager' &' provider' theo dòng trong câu hỏi: 'Location location = locationManager.getLastKnownLocation (nhà cung cấp);' – weston

+0

@Michal nếu bạn không làm điều đó và lưu trữ vị trí cuối cùng, thì ngoài ra gây ra lỗi mà bạn nói đến, bạn sẽ không được hưởng lợi từ các ứng dụng khác yêu cầu vị trí. – weston

1

Mỗi vị trí có thời gian thuộc tính. Nhận nó với getTime(). So sánh nó với thời gian hiện tại. (Tính toán sự khác biệt). Điều này mang lại cho bạn "tuổi".

5

Location.getTime() thực sự không phải là cách tốt nhất để tìm tuổi của vị trí đã biết cuối cùng.

Từ javadoc:

Return thời gian UTC của sửa chữa này, trong mili giây kể từ ngày 1 tháng 1 năm 1970.

Lưu ý rằng thời gian tính theo giờ UTC trên một thiết bị không phải là đơn điệu: nó có thể nhảy về phía trước hoặc ngược lại không lường trước được. Vì vậy, hãy luôn sử dụng getElapsedRealtimeNanos khi tính toán các khoảng thời gian.

Hai phương pháp sử dụng bao gồm:

SystemClock.elapsedRealtimeNanos(); 
Location.getElapsedRealtimeNanos(); 

Cũng lưu ý rằng LocationManager.lastKnownLocation() có thể trả về null.

7

Xin lỗi để mở lại điều này, nhưng tôi nghĩ câu trả lời của Weston là không chính xác, và tài liệu Android ít gây hiểu lầm nhất.

Cơ sở thời gian cho getTime() là UTC được xác định từ câu NMEA nhận được từ mô-đun GPS, không System.currentTimeMillis(). GPS thời gian là chính xác đến nano giây (nó phải kể từ khi sóng điện từ di chuyển 30cm trong 1ns). Các chỉ biến chứng ở đây là nó có thể được tắt bởi 1s do đến một bước nhảy vọt GPS thứ hai (xem [1]; điều này có thể xảy ra trong vài phút vài năm một lần, giả định rằng GPS đủ thông minh để nhớ bù đắp UTC qua các chu kỳ điện)

Mặt khác, System.currentTimeMillis() có thể bị tắt theo một số giây/phút do trôi hoặc thậm chí nhiều hơn nếu người dùng đặt thời gian/ngày không chính xác.

Vì vậy, chỉ có giải pháp thực pre-API 17 là để nhận cập nhật vị trí thường xuyên và mỗi bản ghi thời gian timestamp của riêng bạn dựa trên SystemClock.elapsedRealtime().

Tôi vừa thử điều này trên Samsung S4, hãy sửa tôi nếu điện thoại khác cho kết quả khác nhau. Tôi nghi ngờ nó, mặc dù.

[1] http://en.wikipedia.org/wiki/Global_Positioning_System#Leap_seconds

+0

Tôi nghĩ bạn đã đúng. Chỉ mới thấy điều này một cách tình cờ. Bạn nên đăng bình luận như một bình luận về câu trả lời của tôi hoặc nếu không tôi sẽ không nhìn thấy nó. – weston

+0

Tôi đã thêm thông tin về cách nó nên được sử dụng – weston

+0

Nếu tôi nhận được một upvote, tôi sẽ có đủ danh tiếng để gửi ý kiến ​​:) (điều này có vẻ là một ngoại lệ kể từ khi tôi đang trả lời bài của riêng tôi) –

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