0

How can I get my current coordinates accurately like Google Maps?

By now, I have used getLastLocation - it worked, but I get the same coordinates for the same area of 20 meters - it's not that accurate. In Google Maps you can see accuracy of about 3 meters. How can I achive this?

I'm interested only in the coordinates

Ziv Sion
  • 424
  • 4
  • 14
  • You can use the location data available for Android devices. You can follow the Maps SDK for Android official documentation to get you started with this: https://developers.google.com/maps/documentation/android-sdk/location – jabamataro Aug 27 '21 at 16:59
  • 1
    Duplicate of [How do I get the current GPS location programmatically in Android?](https://stackoverflow.com/questions/1513485/how-do-i-get-the-current-gps-location-programmatically-in-android) – MrUpsidown Sep 01 '21 at 14:30

2 Answers2

1

after user grants location permission, you can do the following. 1- ask user to enable GPS for HIGH ACCURACY location 2- use fusedLocationProviderClient.getCurrentLocation() method to get user current location

private fun askToEnableGPS() {
        LocationServices.getSettingsClient(requireActivity())
            .checkLocationSettings(
                LocationSettingsRequest.Builder()
                    .addLocationRequest(LocationRequest.create().apply {
                        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
                    }).build()
            )
            .addOnSuccessListener {
                //  GPS is already enable, callback GPS status through listener
                getCurrentUserLocation()
            }
            .addOnFailureListener { e ->
                when ((e as ApiException).statusCode) {
                    LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                        // system open location
                        val rae = e as ResolvableApiException
                        launchGPS.launch(IntentSenderRequest.Builder(rae.resolution).build())

                    } catch (sie: IntentSender.SendIntentException) {
                        Log.i(
                            TAG,
                            "PendingIntent unable to execute request."
                        )
                        viewModel.handleNoGPS()
                    }
                    LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
                        Log.i(
                            TAG,
                            "SETTINGS CHANGE UNAVAILABLE"
                        )
                        viewModel.handleNoGPS()
                    }
                }

            }
    }

    private val launchGPS =
        registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result ->
            if (result.resultCode == AppCompatActivity.RESULT_OK) {
                getCurrentUserLocation()
            } else {
                MaterialAlertDialogBuilder(requireContext())
                    .setMessage(getString(R.string.gps_in_need_message))
                    .setPositiveButton(getString(R.string.confirm)) { dialog, _ ->
                        dialog.dismiss()
                        // retry here asking for GPS permission
                    }
                    .setNegativeButton(getString(R.string.get_default)) { dialog, _ ->
                        dialog.dismiss()
                        viewModel.handleNoGPS()
                    }
                    .setCancelable(false)
                    .show()
            }
        }

    fun getCurrentUserLocation() {
        fusedLocationProviderClient.getCurrentLocation(
            LocationRequest.PRIORITY_HIGH_ACCURACY,
            object : CancellationToken() {
                override fun isCancellationRequested(): Boolean = false

                override fun onCanceledRequested(p0: OnTokenCanceledListener): CancellationToken =
                    this

            }
        )
            .addOnSuccessListener {
                // here is user current location
                viewModel.setSelectedByLocation(it.longitude, it.latitude)

            }
            .addOnFailureListener {
                MaterialAlertDialogBuilder(requireContext())
                    .setMessage(getString(R.string.failed_to_get_current_location))
                    .setPositiveButton(getString(R.string.retry)) { dialog, _ ->
                        dialog.dismiss()
                        // retry getCurrentUserLocation or askToEnableGPS
                    }
                    .setNegativeButton(getString(R.string.get_default)) { dialog, _ ->
                        dialog.dismiss()
                        // handle failure in getting current location
                    }
                    .setCancelable(false)
                    .show()
            }
    }
Ramy Ibrahim
  • 656
  • 4
  • 19
-1

There are a few things you need to do. Make sure you have permission, make sure user has his GPS is enabled or not. You need to make a location manager and a location listener that updates every time it changes. See below for the different codes.

Add this to the manifest file to get permission

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Create a location manager

LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);

Check if GPS is on

try {
    gps_enabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}

try {
    network_enabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}
if(!gps_enabled && !network_enabled){
// It's not enabled address the problem here
}

Create Listener

LocationListener locationListener = new MyLocationListener();
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 5000, 10, locationListener);

Listener Class Sample Code

/*---------- Listener class to get coordinates ------------- */
private class MyLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location loc) {
        editLocation.setText("");
        pb.setVisibility(View.INVISIBLE);
        Toast.makeText(
                getBaseContext(),
                "Location changed: Lat: " + loc.getLatitude() + " Lng: "
                    + loc.getLongitude(), Toast.LENGTH_SHORT).show();
        String longitude = "Longitude: " + loc.getLongitude();
        Log.v(TAG, longitude);
        String latitude = "Latitude: " + loc.getLatitude();
        Log.v(TAG, latitude);

        /*------- To get city name from coordinates -------- */
        String cityName = null;
        Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
        List<Address> addresses;
        try {
            addresses = gcd.getFromLocation(loc.getLatitude(),
                    loc.getLongitude(), 1);
            if (addresses.size() > 0) {
                System.out.println(addresses.get(0).getLocality());
                cityName = addresses.get(0).getLocality();
            }
        }
catch (IOException e) {
            e.printStackTrace();
        }
        String s = longitude + "\n" + latitude + "\n\nMy Current City is: "
            + cityName;
        editLocation.setText(s);
    }

    @Override
    public void onProviderDisabled(String provider) {}

    @Override
    public void onProviderEnabled(String provider) {}

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}
}
Drivers Sea
  • 446
  • 2
  • 10