英文:
Jumping gps location in android 10
问题
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;
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();
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;
}
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;
}
}
});
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();
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();
}
}
}
英文:
I use location service in my navigation app. The service get location per second. But jumping gps location is like this photo:
In the service used the GoogleApiClient and LocationListener for get best last location. Also used broadcast for send result to app.
and my location service is:
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();
}
}
}
Thanks about your help.
答案1
得分: 0
你可以设置一个条件语句(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 的阈值。
英文:
You can set a condition statement (if
) to check if that is fake or not.
Change your code on timerTask
to something like this:
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();
}
};
Value 0.6 is a threshold for filter jump GPS.
答案2
得分: 0
最好规范智能手机中跳跃的GPS信号的方法是删除低准确度的位置。
而且低速度时位置准确度较低。
希望这种方法有助于解决这个问题。
英文:
The best way to normalize jumping gps in smartphone is remove locations that the low accuracy.
Also the location accuracy is low on low speeds.
I hope this way useful to resolve this problem.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论