Я наблюдаю странное поведение, наблюдая за временем обновления местоположений с помощью GPS LocationListener.
Иногда (хотя и с перерывами) я вижу, что у обновленного местоположения есть временная метка за доли секунды (несмотря на то, что минимальное обновление устанавливается равным 5000 миллисекундам в requestUpdates) или иногда даже раньше , чем предыдущее местоположение?
Пример обоих, рассматриваемых как доли секунды перед предыдущим местоположением (вывод logcat, отредактированный для ясности) :
GpsTracker_v4: onLocationChanged: Warning: location update is older than previous location
D/GpsTracker_v4:
previous location:
provider: network
time:20/02/22 06:07:17.468
---
new location:
provider: network
time: 20/02/22 06:07:17.467
Я уже достаточно зарегистрировался, чтобы (справедливо) уверенно утверждать, что это не из-за конфликта gps / сетевого провайдера или из-за того, что он разнесен только на миллисекунды (например, более длительный период до секунд) долго включается внизу поста)
Весь мой класс трекера (за исключением десятков журналов отладки):
public class GpsTracker_v4 {
/*--------------------------------------
CONSTANTS
--------------------------------------*/
private static final String TAG = GpsTracker_v4.class.getSimpleName();
// location updates interval - 5sec
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 5000;
/*--------------------------------------
MEMBER VARIABLES
--------------------------------------*/
//---VARIABLES---
Context context;
LocationManager locationManager;
LocationListener locationListener;
Location previousLocation = null;
/*--------------------------------------
CONSTRUCTOR
--------------------------------------*/
//-create manager and initialise location listener
public GpsTracker_v4(Context c) {
this.context = c;
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
if (previousLocation != null) {
//check location update is more recent than previous
if (checkUpdateTime(location)) {
Log.d(TAG, "onLocationChanged: new location more recent");
} else {
Log.w(TAG, "onLocationChanged: Warning: location update is " +
"older than previous location");
}
Log.d(TAG, "previous location:\n" +
"provider: " + previousLocation.getProvider() + "\n" +
"time:" + getDateString(previousLocation.getTime()) + "\n" +
"---\n" +
"new location:\n" +
"provider: " + location.getProvider() + "\n" +
"time: " + getDateString(location.getTime()));
//check location is more accurate than previous location
if (checkUpdateAccuracy(location)) {
Log.d(TAG, "onLocationChanged: location update is more accurate");
} else {
Log.w(TAG, "onLocationChanged: Warning: location update is " +
"less accurate or equal to previous");
}
Log.d(TAG, "Prev location:\n" +
"provider: " + previousLocation.getProvider() + "\n" +
"accuracy: " + previousLocation.getAccuracy() + "\n" +
"---\n" +
"New location:\n" +
"provider: " + location.getProvider() + "\n" +
"accuracy: " + location.getAccuracy());
} else {
//no previous location yet
Log.d(TAG, "onLocationChanged: previousLocation is null: " +
"using first location update:");
}
//replace previous location with updated
previousLocation = location;
//debugging attempt: remove all content of location
location = null;
} else {
//null location passed
Log.e(TAG, "onLocationChanged: Error: passed location is NULL");
//todo: handle
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
//todo:
}
@Override
public void onProviderEnabled(String s) {
//todo:
}
@Override
public void onProviderDisabled(String s) {
//todo:
}
};
beginRequestUpdates();
}
/*--------------------------------------
METHODS
--------------------------------------*/
//-begin requesting updates from both gps and network providers
public void beginRequestUpdates() {
//permission check (IDE insists its done here, not earlier or in another method)
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(
context, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG, "checkPermission: Error: Permission not been granted.);
return;
}
//begin GPs updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
UPDATE_INTERVAL_IN_MILLISECONDS,
0,
locationListener,
Looper.getMainLooper());
Log.d(TAG, "beginRequestUpdates: GPS updates requested");
//begin network updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
UPDATE_INTERVAL_IN_MILLISECONDS,
0,
locationListener,
Looper.getMainLooper());
Log.d(TAG, "beginRequestUpdates: Network updates requested");
}
/*--------------------------------------
HELPER METHODS
--------------------------------------*/
//-return true if time of location update is more recent than previous update time
public boolean checkUpdateTime(Location location) {
return location.getTime() > previousLocation.getTime();
}
//-return true if location update is more accurate than previous location
public boolean checkUpdateAccuracy(Location location) {
return location.getAccuracy() < previousLocation.getAccuracy();
}
//-get user-readable date/time from milli (in year-month-day format)
private String getDateString(long milliSeconds) {
String dateFormat = "yy/MM/dd hh:mm:ss.SSS";
SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
return formatter.format(calendar.getTime());
}
public void printLocation(Location location) {
System.out.println("" +
"Provider: " + location.getProvider() + "\n" +
"Latitude: " + location.getLatitude() + "\n" +
"Longitude: " + location.getLongitude() + "\n" +
"Accuracy: " + location.getAccuracy() + "\n" +
"Time: " + getDateString(location.getTime()) + "\n");
}
/*--------------------------------------
MUTATORS
--------------------------------------*/
//-set listener from outside class
public void setListener(LocationListener listener) {
this.locationListener = listener;
}
}
В чем причина такого поведения?
Редактировать
Вот лучший пример того, как обновление местоположения обновляется до предыдущей отметки:
updated location:
Time: 20/02/22 06:44:57.346
previous location:
Time: 20/02/22 06:45:21.370