Search code examples
androidandroid-gps

How to get exact GPS position in Android on click


I am trying to get an exact GPS location on the click of a button. I am using the fusesLocationProviderClient and have FINE_LOCATION permission.

private void getCurrentGPSLocation() {
   // get the new location from the fused client
   // update the UI - i.e. set all properties in their associated text view items

   //Initialize new location request
        LocationRequest locationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                .setInterval(10000)
                .setFastestInterval(1000)
                .setNumUpdates(1);
  //Initialize location call back
        LocationCallback locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                //Initialize location1
                Location location1 = locationResult.getLastLocation();
   //Set Accuracy
            double accura1 = location1.getAccuracy();}
};
        //Request location updates
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        fusedLocationProviderClient.requestLocationUpdates(locationRequest
                , locationCallback, Looper.myLooper());
    }

Then I am getting the coordinates from the location1 variable as I am getting accuracy from it. The problem is that this is very unprecise as I am getting an accuracy of 800-1000m. After having opened GoogleMaps for a few seconds and then returning to my app calling getLastLocation(); with another button (not part of my code sample), I am getting an accuracy of 4-5m. When using my code again the accuracy again is 800-1000m. So my question is, how I can change my code to get this kind of accuracy into my getCurrentGLSLpcation() method.


Solution

  • I have found a solution for it after having tried your ideas:

     private void getCurrentGPSLocation() {
            // get the new location from the fused client
            // update the UI - i.e. set all properties in their associated text view items
    
            //Initialize new location request
            LocationRequest locationRequest = new LocationRequest()
                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                    .setInterval(2500)
                    .setFastestInterval(2000)
                    .setNumUpdates(8);
    
            //Initialize location call back
            LocationCallback locationCallback = new LocationCallback() {
                @Override
    
                public void onLocationResult(LocationResult locationResult) {
                    //Initialize location1
                    Location location1 = locationResult.getLastLocation();
                    //Set latitude
                    tvLatitude.setText(String.valueOf(location1.getLatitude()));
                    //Set longitude
                    tvLongitude.setText(String.valueOf(location1.getLongitude()));
                    //Set Accuracy
                    double accura1 = location1.getAccuracy();
                    tvAccuracy.setText(new DecimalFormat("##.##").format(accura1) + " m");
                    //Set Altitude
                    double altit1 = location1.getAltitude();
                    tvAltitude.setText(new DecimalFormat("##.##").format(altit1) + " m");
    
                    //Get Adress
                    double longitude1 = location1.getLongitude();
                    double latitude1 = location1.getLatitude();
                    Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
                    try {
                        List<Address> listAddresses = geocoder.getFromLocation(latitude1, longitude1, 1);
                        if (null != listAddresses && listAddresses.size() > 0) {
                            String _Location1 = listAddresses.get(0).getAddressLine(0);
                            //Set Location
                            tvLocation.setText(String.valueOf(_Location1));
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                    //Set Update Time
                    TextView textView = findViewById(R.id.tv_update);
                    SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy 'um ' HH:mm:ss z");
                    String currentDateandTime = sdf.format(new Date());
                    textView.setText(currentDateandTime);
    
    
                }
    
            };
            //Call method to insert data into database
            (new Handler()).postDelayed(this::OnReg, 30000);
            //OnReg();
            //Call Method to save data in SharedPreferences
            (new Handler()).postDelayed(this::saveData, 30000);
            //saveData();
            //call Method to save data in Internal File
            (new Handler()).postDelayed(this::saveToFile, 30000);
            //saveToFile();
            //Request location updates
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            fusedLocationProviderClient.requestLocationUpdates(locationRequest
                    , locationCallback, Looper.myLooper());
        }
    

    So this is the complete code with the textviews being updated from the location. Basically I have 8 location updates before taking the last and therefore most precise location to call my methods which save the location in a database (OnReg), an internal file (saveToFile) and the SharedPreferences(saveData). These methods are called with a delay of 30 seconds to make sure the location is accurate.