在 android 10 中跳跃 gps 位置
Jumping gps location in android 10
我在我的导航应用程序中使用定位服务。该服务每秒获取位置。但是跳跃的gps定位是这样的照片:
在该服务中,使用 GoogleApiClient 和 LocationListener 获取最佳最后位置。还使用广播将结果发送到应用程序。
我的定位服务是:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = LocationFinder.class.getSimpleName();
private Location location;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private static final long UPDATE_INTERVAL = 1000, FASTEST_INTERVAL = 1000;
private Context context;
// Send Data to View with BroadCast
static final public String GDS_RESULT = "AE_Find_Location";
static final public String GDS_SPEED = "Service_SPD";
static final public String GDS_LAT = "Service_lat";
static final public String GDS_LON = "Service_lon";
static final public String GDS_BEARING = "Service_bearing";
private LocalBroadcastManager broadcaster;
private int SEND_LOCATION_TIMER = 30000;
public static final int REQUEST_CHECK_SETTINGS = 100;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
// we build google api client
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
broadcaster = LocalBroadcastManager.getInstance(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (googleApiClient != null)
googleApiClient.connect();
startSendData();
return START_STICKY;
}
private ArrayList<Location> locations = new ArrayList<>();
private ConcurrentLinkedQueue<Coordinate> queue = new ConcurrentLinkedQueue<>();
private Timer timer;
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
if (location == null) return;
sendResult(location);
}
}).start();
}
};
public void startSendData() {
if (timer != null) {
return;
}
timer = new Timer();
timer.scheduleAtFixedRate(timerTask, 0, 1000);
}
public void stopSendData() {
if (timer == null) return;
timer.cancel();
timer = null;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Log.i(TAG, "onResult: connected");
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
googleApiClient,
builder.build()
);
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// NO need to show the dialog;
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(MyApplication.currentActivity, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
//failed to show dialog
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are unavailable so not possible to show any dialog now
break;
}
}
});
// Permissions ok, we get last location
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
startLocationUpdates();
}
private void startLocationUpdates() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
this.location = location;
}
}
@Override
public void onDestroy() {
super.onDestroy();
// stop location updates
if (googleApiClient != null && googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
}
stopSendData();
}
public void sendResult(Location location) {
try {
if (location == null) return;
String lat = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLatitude()));
String lng = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLongitude()));
Intent intent = new Intent(GDS_RESULT);
intent.putExtra(GDS_SPEED, location.getSpeed());
intent.putExtra(GDS_LAT, Double.valueOf(lat));
intent.putExtra(GDS_LON, Double.valueOf(lng));
intent.putExtra(GDS_BEARING, location.getBearing());
broadcaster.sendBroadcast(intent);
if (MyApplication.prefManager.getApiRequestTime() + SEND_LOCATION_TIMER > Calendar.getInstance().getTimeInMillis())
return;
MyApplication.prefManager.setApiRequestTime(Calendar.getInstance().getTimeInMillis());
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
感谢您的帮助。
您可以设置一个条件语句 (if
) 来检查它是否是假的。
将 timerTask
上的代码更改为如下内容:
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
if (location == null) return;
if (lastLocation != null) {
if (Math.abs((lastLocation.distanceTo(location)) / (location.getTime() - lastLocation.getTime())) > 0.06 && counter<5) {
sendResult(lastLocation);
counter++;
return;
}
}
counter = 0;
sendResult(location);
lastLocation = location;
}
}).start();
}
};
值 0.6 是过滤跳跃 GPS 的阈值。
在智能手机中规范跳跃式 GPS 的最佳方法是删除 低精度 的位置。
低速时定位精度也很低。
我希望这种方式对解决这个问题有用。
我在我的导航应用程序中使用定位服务。该服务每秒获取位置。但是跳跃的gps定位是这样的照片:
在该服务中,使用 GoogleApiClient 和 LocationListener 获取最佳最后位置。还使用广播将结果发送到应用程序。 我的定位服务是:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final String TAG = LocationFinder.class.getSimpleName();
private Location location;
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private static final long UPDATE_INTERVAL = 1000, FASTEST_INTERVAL = 1000;
private Context context;
// Send Data to View with BroadCast
static final public String GDS_RESULT = "AE_Find_Location";
static final public String GDS_SPEED = "Service_SPD";
static final public String GDS_LAT = "Service_lat";
static final public String GDS_LON = "Service_lon";
static final public String GDS_BEARING = "Service_bearing";
private LocalBroadcastManager broadcaster;
private int SEND_LOCATION_TIMER = 30000;
public static final int REQUEST_CHECK_SETTINGS = 100;
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
// we build google api client
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
broadcaster = LocalBroadcastManager.getInstance(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (googleApiClient != null)
googleApiClient.connect();
startSendData();
return START_STICKY;
}
private ArrayList<Location> locations = new ArrayList<>();
private ConcurrentLinkedQueue<Coordinate> queue = new ConcurrentLinkedQueue<>();
private Timer timer;
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
if (location == null) return;
sendResult(location);
}
}).start();
}
};
public void startSendData() {
if (timer != null) {
return;
}
timer = new Timer();
timer.scheduleAtFixedRate(timerTask, 0, 1000);
}
public void stopSendData() {
if (timer == null) return;
timer.cancel();
timer = null;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Log.i(TAG, "onResult: connected");
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
googleApiClient,
builder.build()
);
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// NO need to show the dialog;
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(MyApplication.currentActivity, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
//failed to show dialog
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are unavailable so not possible to show any dialog now
break;
}
}
});
// Permissions ok, we get last location
location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
startLocationUpdates();
}
private void startLocationUpdates() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Override
public void onLocationChanged(Location location) {
if (location != null) {
this.location = location;
}
}
@Override
public void onDestroy() {
super.onDestroy();
// stop location updates
if (googleApiClient != null && googleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
googleApiClient.disconnect();
}
stopSendData();
}
public void sendResult(Location location) {
try {
if (location == null) return;
String lat = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLatitude()));
String lng = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLongitude()));
Intent intent = new Intent(GDS_RESULT);
intent.putExtra(GDS_SPEED, location.getSpeed());
intent.putExtra(GDS_LAT, Double.valueOf(lat));
intent.putExtra(GDS_LON, Double.valueOf(lng));
intent.putExtra(GDS_BEARING, location.getBearing());
broadcaster.sendBroadcast(intent);
if (MyApplication.prefManager.getApiRequestTime() + SEND_LOCATION_TIMER > Calendar.getInstance().getTimeInMillis())
return;
MyApplication.prefManager.setApiRequestTime(Calendar.getInstance().getTimeInMillis());
} catch (NullPointerException e) {
e.printStackTrace();
}
}
}
感谢您的帮助。
您可以设置一个条件语句 (if
) 来检查它是否是假的。
将 timerTask
上的代码更改为如下内容:
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
new Thread(new Runnable() {
@Override
public void run() {
if (location == null) return;
if (lastLocation != null) {
if (Math.abs((lastLocation.distanceTo(location)) / (location.getTime() - lastLocation.getTime())) > 0.06 && counter<5) {
sendResult(lastLocation);
counter++;
return;
}
}
counter = 0;
sendResult(location);
lastLocation = location;
}
}).start();
}
};
值 0.6 是过滤跳跃 GPS 的阈值。
在智能手机中规范跳跃式 GPS 的最佳方法是删除 低精度 的位置。 低速时定位精度也很低。 我希望这种方式对解决这个问题有用。