在安卓10中跳转GPS位置

huangapple go评论111阅读模式
英文:

Jumping gps location in android 10

问题

  1. public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
  2. private static final String TAG = LocationFinder.class.getSimpleName();
  3. private Location location;
  4. private GoogleApiClient googleApiClient;
  5. private LocationRequest locationRequest;
  6. private static final long UPDATE_INTERVAL = 1000, FASTEST_INTERVAL = 1000;
  7. private Context context;
  8. static final public String GDS_RESULT = "AE_Find_Location";
  9. static final public String GDS_SPEED = "Service_SPD";
  10. static final public String GDS_LAT = "Service_lat";
  11. static final public String GDS_LON = "Service_lon";
  12. static final public String GDS_BEARING = "Service_bearing";
  13. private LocalBroadcastManager broadcaster;
  14. private int SEND_LOCATION_TIMER = 30000;
  15. public static final int REQUEST_CHECK_SETTINGS = 100;
  16. @Override
  17. public void onCreate() {
  18. super.onCreate();
  19. context = getApplicationContext();
  20. googleApiClient = new GoogleApiClient.Builder(this)
  21. .addApi(LocationServices.API)
  22. .addConnectionCallbacks(this)
  23. .addOnConnectionFailedListener(this).build();
  24. broadcaster = LocalBroadcastManager.getInstance(this);
  25. }
  26. @Override
  27. public int onStartCommand(Intent intent, int flags, int startId) {
  28. if (googleApiClient != null)
  29. googleApiClient.connect();
  30. startSendData();
  31. return START_STICKY;
  32. }
  33. private ArrayList<Location> locations = new ArrayList<>();
  34. private ConcurrentLinkedQueue<Coordinate> queue = new ConcurrentLinkedQueue<>();
  35. private Timer timer;
  36. private TimerTask timerTask = new TimerTask() {
  37. @Override
  38. public void run() {
  39. new Thread(new Runnable() {
  40. @Override
  41. public void run() {
  42. if (location == null) return;
  43. sendResult(location);
  44. }
  45. }).start();
  46. }
  47. };
  48. public void startSendData() {
  49. if (timer != null) {
  50. return;
  51. }
  52. timer = new Timer();
  53. timer.scheduleAtFixedRate(timerTask, 0, 1000);
  54. }
  55. public void stopSendData() {
  56. if (timer == null) return;
  57. timer.cancel();
  58. timer = null;
  59. }
  60. @Nullable
  61. @Override
  62. public IBinder onBind(Intent intent) {
  63. return null;
  64. }
  65. @Override
  66. public void onConnected(Bundle bundle) {
  67. if (ActivityCompat.checkSelfPermission(this,
  68. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  69. && ActivityCompat.checkSelfPermission(this,
  70. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  71. return;
  72. }
  73. LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
  74. .addLocationRequest(locationRequest);
  75. builder.setAlwaysShow(true);
  76. PendingResult<LocationSettingsResult> result =
  77. LocationServices.SettingsApi.checkLocationSettings(
  78. googleApiClient,
  79. builder.build()
  80. );
  81. result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
  82. @Override
  83. public void onResult(LocationSettingsResult locationSettingsResult) {
  84. final Status status = locationSettingsResult.getStatus();
  85. switch (status.getStatusCode()) {
  86. case LocationSettingsStatusCodes.SUCCESS:
  87. // NO need to show the dialog;
  88. break;
  89. case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
  90. try {
  91. status.startResolutionForResult(MyApplication.currentActivity, REQUEST_CHECK_SETTINGS);
  92. } catch (IntentSender.SendIntentException e) {
  93. //failed to show dialog
  94. }
  95. break;
  96. case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
  97. // Location settings are unavailable so not possible to show any dialog now
  98. break;
  99. }
  100. }
  101. });
  102. location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
  103. startLocationUpdates();
  104. }
  105. private void startLocationUpdates() {
  106. locationRequest = new LocationRequest();
  107. locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  108. locationRequest.setInterval(UPDATE_INTERVAL);
  109. locationRequest.setFastestInterval(FASTEST_INTERVAL);
  110. if (ActivityCompat.checkSelfPermission(this,
  111. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  112. && ActivityCompat.checkSelfPermission(this,
  113. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  114. }
  115. LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
  116. }
  117. @Override
  118. public void onConnectionSuspended(int i) {
  119. }
  120. @Override
  121. public void onConnectionFailed(ConnectionResult connectionResult) {
  122. }
  123. @Override
  124. public void onLocationChanged(Location location) {
  125. if (location != null) {
  126. this.location = location;
  127. }
  128. }
  129. @Override
  130. public void onDestroy() {
  131. super.onDestroy();
  132. if (googleApiClient != null && googleApiClient.isConnected()) {
  133. LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
  134. googleApiClient.disconnect();
  135. }
  136. stopSendData();
  137. }
  138. public void sendResult(Location location) {
  139. try {
  140. if (location == null) return;
  141. String lat = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLatitude()));
  142. String lng = HelperNumber.convertNumber(new DecimalFormat("##.#####").format(location.getLongitude()));
  143. Intent intent = new Intent(GDS_RESULT);
  144. intent.putExtra(GDS_SPEED, location.getSpeed());
  145. intent.putExtra(GDS_LAT, Double.valueOf(lat));
  146. intent.putExtra(GDS_LON, Double.valueOf(lng));
  147. intent.putExtra(GDS_BEARING, location.getBearing());
  148. broadcaster.sendBroadcast(intent);
  149. if (MyApplication.prefManager.getApiRequestTime() + SEND_LOCATION_TIMER > Calendar.getInstance().getTimeInMillis())
  150. return;
  151. MyApplication.prefManager.setApiRequestTime(Calendar.getInstance().getTimeInMillis());
  152. } catch (NullPointerException e) {
  153. e.printStackTrace();
  154. }
  155. }
  156. }
英文:

I use location service in my navigation app. The service get location per second. But jumping gps location is like this photo:

在安卓10中跳转GPS位置

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:

  1. public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
  2. private static final String TAG = LocationFinder.class.getSimpleName();
  3. private Location location;
  4. private GoogleApiClient googleApiClient;
  5. private LocationRequest locationRequest;
  6. private static final long UPDATE_INTERVAL = 1000, FASTEST_INTERVAL = 1000;
  7. private Context context;
  8. // Send Data to View with BroadCast
  9. static final public String GDS_RESULT = &quot;AE_Find_Location&quot;;
  10. static final public String GDS_SPEED = &quot;Service_SPD&quot;;
  11. static final public String GDS_LAT = &quot;Service_lat&quot;;
  12. static final public String GDS_LON = &quot;Service_lon&quot;;
  13. static final public String GDS_BEARING = &quot;Service_bearing&quot;;
  14. private LocalBroadcastManager broadcaster;
  15. private int SEND_LOCATION_TIMER = 30000;
  16. public static final int REQUEST_CHECK_SETTINGS = 100;
  17. @Override
  18. public void onCreate() {
  19. super.onCreate();
  20. context = getApplicationContext();
  21. // we build google api client
  22. googleApiClient = new GoogleApiClient.Builder(this)
  23. .addApi(LocationServices.API)
  24. .addConnectionCallbacks(this)
  25. .addOnConnectionFailedListener(this).build();
  26. broadcaster = LocalBroadcastManager.getInstance(this);
  27. }
  28. @Override
  29. public int onStartCommand(Intent intent, int flags, int startId) {
  30. if (googleApiClient != null)
  31. googleApiClient.connect();
  32. startSendData();
  33. return START_STICKY;
  34. }
  35. private ArrayList&lt;Location&gt; locations = new ArrayList&lt;&gt;();
  36. private ConcurrentLinkedQueue&lt;Coordinate&gt; queue = new ConcurrentLinkedQueue&lt;&gt;();
  37. private Timer timer;
  38. private TimerTask timerTask = new TimerTask() {
  39. @Override
  40. public void run() {
  41. new Thread(new Runnable() {
  42. @Override
  43. public void run() {
  44. if (location == null) return;
  45. sendResult(location);
  46. }
  47. }).start();
  48. }
  49. };
  50. public void startSendData() {
  51. if (timer != null) {
  52. return;
  53. }
  54. timer = new Timer();
  55. timer.scheduleAtFixedRate(timerTask, 0, 1000);
  56. }
  57. public void stopSendData() {
  58. if (timer == null) return;
  59. timer.cancel();
  60. timer = null;
  61. }
  62. @Nullable
  63. @Override
  64. public IBinder onBind(Intent intent) {
  65. return null;
  66. }
  67. @Override
  68. public void onConnected(Bundle bundle) {
  69. if (ActivityCompat.checkSelfPermission(this,
  70. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  71. &amp;&amp; ActivityCompat.checkSelfPermission(this,
  72. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  73. return;
  74. }
  75. Log.i(TAG, &quot;onResult: connected&quot;);
  76. LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
  77. .addLocationRequest(locationRequest);
  78. builder.setAlwaysShow(true);
  79. PendingResult&lt;LocationSettingsResult&gt; result =
  80. LocationServices.SettingsApi.checkLocationSettings(
  81. googleApiClient,
  82. builder.build()
  83. );
  84. result.setResultCallback(new ResultCallback&lt;LocationSettingsResult&gt;() {
  85. @Override
  86. public void onResult(LocationSettingsResult locationSettingsResult) {
  87. final Status status = locationSettingsResult.getStatus();
  88. switch (status.getStatusCode()) {
  89. case LocationSettingsStatusCodes.SUCCESS:
  90. // NO need to show the dialog;
  91. break;
  92. case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
  93. try {
  94. status.startResolutionForResult(MyApplication.currentActivity, REQUEST_CHECK_SETTINGS);
  95. } catch (IntentSender.SendIntentException e) {
  96. //failed to show dialog
  97. }
  98. break;
  99. case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
  100. // Location settings are unavailable so not possible to show any dialog now
  101. break;
  102. }
  103. }
  104. });
  105. // Permissions ok, we get last location
  106. location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
  107. startLocationUpdates();
  108. }
  109. private void startLocationUpdates() {
  110. locationRequest = new LocationRequest();
  111. locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  112. locationRequest.setInterval(UPDATE_INTERVAL);
  113. locationRequest.setFastestInterval(FASTEST_INTERVAL);
  114. if (ActivityCompat.checkSelfPermission(this,
  115. Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
  116. &amp;&amp; ActivityCompat.checkSelfPermission(this,
  117. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  118. }
  119. LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
  120. }
  121. @Override
  122. public void onConnectionSuspended(int i) {
  123. }
  124. @Override
  125. public void onConnectionFailed(ConnectionResult connectionResult) {
  126. }
  127. @Override
  128. public void onLocationChanged(Location location) {
  129. if (location != null) {
  130. this.location = location;
  131. }
  132. }
  133. @Override
  134. public void onDestroy() {
  135. super.onDestroy();
  136. // stop location updates
  137. if (googleApiClient != null &amp;&amp; googleApiClient.isConnected()) {
  138. LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
  139. googleApiClient.disconnect();
  140. }
  141. stopSendData();
  142. }
  143. public void sendResult(Location location) {
  144. try {
  145. if (location == null) return;
  146. String lat = HelperNumber.convertNumber(new DecimalFormat(&quot;##.#####&quot;).format(location.getLatitude()));
  147. String lng = HelperNumber.convertNumber(new DecimalFormat(&quot;##.#####&quot;).format(location.getLongitude()));
  148. Intent intent = new Intent(GDS_RESULT);
  149. intent.putExtra(GDS_SPEED, location.getSpeed());
  150. intent.putExtra(GDS_LAT, Double.valueOf(lat));
  151. intent.putExtra(GDS_LON, Double.valueOf(lng));
  152. intent.putExtra(GDS_BEARING, location.getBearing());
  153. broadcaster.sendBroadcast(intent);
  154. if (MyApplication.prefManager.getApiRequestTime() + SEND_LOCATION_TIMER &gt; Calendar.getInstance().getTimeInMillis())
  155. return;
  156. MyApplication.prefManager.setApiRequestTime(Calendar.getInstance().getTimeInMillis());
  157. } catch (NullPointerException e) {
  158. e.printStackTrace();
  159. }
  160. }
  161. }

Thanks about your help.

答案1

得分: 0

你可以设置一个条件语句(if)来检查是否为伪造。

将你的timerTask代码更改为类似以下内容:

  1. private TimerTask timerTask = new TimerTask() {
  2. @Override
  3. public void run() {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. if (location == null) return;
  8. if (lastLocation != null) {
  9. if (Math.abs((lastLocation.distanceTo(location)) / (location.getTime() - lastLocation.getTime())) > 0.06 && counter < 5) {
  10. sendResult(lastLocation);
  11. counter++;
  12. return;
  13. }
  14. }
  15. counter = 0;
  16. sendResult(location);
  17. lastLocation = location;
  18. }
  19. }).start();
  20. }
  21. };

值 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:

  1. private TimerTask timerTask = new TimerTask() {
  2. @Override
  3. public void run() {
  4. new Thread(new Runnable() {
  5. @Override
  6. public void run() {
  7. if (location == null) return;
  8. if (lastLocation != null) {
  9. if (Math.abs((lastLocation.distanceTo(location)) / (location.getTime() - lastLocation.getTime())) &gt; 0.06 &amp;&amp; counter&lt;5) {
  10. sendResult(lastLocation);
  11. counter++;
  12. return;
  13. }
  14. }
  15. counter = 0;
  16. sendResult(location);
  17. lastLocation = location;
  18. }
  19. }).start();
  20. }
  21. };

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.

huangapple
  • 本文由 发表于 2020年7月26日 13:25:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63096406.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定