Java Android onLocationChanged不遵守更新最短持续时间,更新时间早于上一次更新
通过GPS LocationListener监控更新位置的时间,我遇到了一些奇怪的行为 有时(虽然是间歇性的),我会看到更新的位置有一个时间戳,时间戳只差几分之一秒(尽管requestUpdates中的最小更新设置为5000毫秒),或者有时甚至比前一个位置更早 前一位置前一秒(logcat输出,为清晰起见进行了编辑)的两个示例: 到目前为止,我已经登录了足够多的日志(相当)自信地宣称这不是由于gps/网络提供商冲突,也不是因为它仅相隔毫秒(例如,文章底部包含长达秒的较长持续时间) 我的整个tracker类(减去几十个调试日志):Java Android onLocationChanged不遵守更新最短持续时间,更新时间早于上一次更新,java,android,android-gps,on-location-changed,Java,Android,Android Gps,On Location Changed,通过GPS LocationListener监控更新位置的时间,我遇到了一些奇怪的行为 有时(虽然是间歇性的),我会看到更新的位置有一个时间戳,时间戳只差几分之一秒(尽管requestUpdates中的最小更新设置为5000毫秒),或者有时甚至比前一个位置更早 前一位置前一秒(logcat输出,为清晰起见进行了编辑)的两个示例: 到目前为止,我已经登录了足够多的日志(相当)自信地宣称这不是由于gps/网络提供商冲突,也不是因为它仅相隔毫秒(例如,文章底部包含长达秒的较长持续时间) 我的整个tra
我的第一个想法是,“好吧,如果这是GPS提供商,那么我会担心的”,但是
getTime()
文档不厌其烦地提到设备上的UTC时间不是单调的…
,这就增加了时间黑客直接来自系统时钟的可能性,你的系统时钟可能会改变。感谢大家提醒我,我将编写一个活动来显示这些值,并通过GPS在室外运行一些实验,看看它是否也会这样做。您知道使用网络提供商的时间价值来自哪里吗?(移动设备?wifi路由器?运行AndroidStudio?等的笔记本电脑?(在任何情况下,是什么原因导致系统时钟不稳定?自从阅读了您的回复后,我在网上查看了一下,但到目前为止还没有任何线索。这些时间戳很可能来自您的系统时钟。不连续性出乎意料地大,但可能您的设备有缺陷,或者您居住的地区的手机网络时钟不同步,或者您的LAN NTP提供商不同于您的移动NTP提供商。我只是猜测。但是,您可以自己花点时间进行黑客攻击(使用System.currentTimeMillis()
),看看与getTime()
)相比,它们有多有序。感谢您的想法,我已经开始将系统和位置millis一起打印,并且存在不一致性(预计这是一部通过亚洲开发银行连接的电话)由于我不知道该怎么处理它们,而且我在这方面浪费了更多的时间,我打算扔掉任何“错误”的位置以节省时间。(我也一直得到相同的值:完全相同的毫秒时间戳,绝对不是代码问题,因为我在onLocationChanged的开头将所有值都放回null,这一定是监听器的特性(mal)功能我可能忽略了这里显而易见的一点:我请求了gps和网络更新,如果其中一个得到了新的位置,那么另一个可能是此时传递给侦听器的位置。我收到了帮助。我的第一个想法是,“如果这是gps提供商,那么我会担心的。”,但接下来是getTime()
文档不厌其烦地提到,设备上的UTC时间不是单调的…
,这增加了这些时间黑客直接来自系统时钟的可能性,并且您的系统时钟可能会发生变化。感谢大家的提醒,我将编写一个活动来显示这些值,并在vi之外运行一些实验一个GPS,看看它是否也有相同的功能。你知道时间值来自于网络提供商吗?(移动设备?wifi路由器?运行AndroidStudio的笔记本电脑?等等?(在任何情况下,是什么原因导致系统时钟不稳定?自从阅读了您的回复后,我在网上查看了一下,但到目前为止还没有任何线索。这些时间戳很可能来自您的系统时钟。不连续性出乎意料地大,但可能您的设备有缺陷,或者您居住的地区的手机网络时钟不同步,或者您的LAN NTP提供商不同于您的移动NTP提供商。我只是猜测。但是,您可以自己花点时间进行黑客攻击(使用System.currentTimeMillis()
),看看与getTime()
)相比,它们有多有序。感谢您的想法,我已经开始将系统和位置millis一起打印,并且存在不一致性(预计这是一部通过亚洲开发银行连接的电话)由于我不知道该怎么处理它们,而且我在这方面浪费了更多的时间,我打算扔掉任何“错误”的位置以节省时间。(我也一直得到相同的值:完全相同的毫秒时间戳,绝对不是代码问题,因为我在onLocationChanged的开头将所有值都放回null,这一定是监听器的特性(mal)功能我可能忽略了这里显而易见的一点:我请求了gps和网络更新,如果其中一个得到了新的位置,那么另一个可能是此时正在传递给侦听器的位置。我感谢您的帮助
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
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