androidgpsfusedlocationproviderclient

Is there a way to get a constant accuracy of 5-10 mts?


I'm trying to build some location apps, and the main problem is the accuracy data (not sure if getAccuracy() is reliable for measuring the error). I read in the forum and i saw some post in which the accuracy was about 5-10 but it always is around 30mts for me.

Currently, I'm using fusedlocationproviderclient, I dont need an API key for this right? Wifi search is enabled, otherwise it jumps to 300~ Another thing, I'm from southamerica, maybe is just more errors for my region.

public class MainActivity extends AppCompatActivity {

private FusedLocationProviderClient cliente;
private LocationRequest locationRequest;
private LocationCallback locationCallback;

@Override
protected void onCreate(Bundle savedInstanceState) {

    locationRequest = new LocationRequest();
    locationRequest.setInterval(5000);
    locationRequest.setFastestInterval(3000);
    locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

    gps_bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (gps_bt.isChecked()) {
                sensor.setText("GPS");
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            } else {
                sensor.setText("Torre celular y wifi");
                locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
            }
        }
    });

    upd_bt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (upd_bt.isChecked()) {
                actualizacion.setText("Encendidas");
                actualizar = true;
                empezarActualizacion();
            } else {
                actualizacion.setText("Apagadas");
                actualizar = false;
                detenerActualizacion();
            }
        }
    });

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            for (Location location : locationResult.getLocations()) {
                latitud.setText(String.valueOf(location.getLatitude()));
                longitud.setText(String.valueOf(location.getLongitude()));
                precision.setText(String.valueOf(location.getAccuracy()));
                if (location.hasAltitude()) {
                    altitud.setText(String.valueOf(location.getAltitude()));
                } else {
                    altitud.setText("No se pudo colectar la altitud");
                }
                if (location.hasSpeed()) {
                    velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
                } else {
                    velocidad.setText("No se puede recuperar la velocidad");
                }
            }
        }
    };

    cliente = LocationServices.getFusedLocationProviderClient(this);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        cliente.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
            @Override
            public void onSuccess(Location location) {
                if (location != null) {
                    latitud.setText(String.valueOf(location.getLatitude()));
                    longitud.setText(String.valueOf(location.getLongitude()));
                    precision.setText(String.valueOf(location.getAccuracy()));
                    if (location.hasAltitude()) {
                        altitud.setText(String.valueOf(location.getAltitude()));
                    } else {
                        altitud.setText("No se pudo colectar la altitud");
                    }
                    if (location.hasSpeed()) {
                        velocidad.setText(String.valueOf(location.getSpeed()) + "m/s");
                    } else {
                        velocidad.setText("No se puede recuperar la velocidad");
                    }
                }
            }
        });
    } else {
        //pedir permisos
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISO_FINE_LOCATION);
        }
    }

}

It always throw 30mts or more and as i mentioned before, i wish to achieve around 10mts if its possible. The manifest file is with FINE_LOCATION. For future uses this is going to work on phone data too (LTE/4g/3g) do i have to give permission for COARSE_LOCATION too? It fusedlocationproviderclient the best option for this purpose? The use of kalman can improve the lat/long data? I did the test on a Samsung S8, but i would like to cover from lollipop. Thank you all.


Solution

  • Keep a constant of 5 to 10 meters on smartphones, still not possible. Because? In some cases you can achieve optimum accuracy, in most cases not. Elements external to the GNSS chip embedded in the devices contribute to the margin of error. For example:

    But there is good news. Devices that promise to be more precise because they will ship chips that support the L5 signal. The L5 signal works totally differently and is more robust in terms of design than the old L1.

    High precision has a major impact on energy consumption, so you should be happy to get a precision of 20, 10 meters in the vast majority of cases.