在 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 的最佳方法是删除 低精度 的位置。 低速时定位精度也很低。 我希望这种方式对解决这个问题有用。