0

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.

ayanu99
  • 63
  • 8
  • remove `.setNumUpdates(1)`, set `.setInterval(5000)`,`.setFastestInterval(4000)` then wait for `onLocationResult` for 5 or 10s , it will have better results. – KuLdip PaTel Mar 12 '21 at 11:32
  • Thanks for your reply. I am actually stuck at how to put the delay for onLocationResult into my code. I have found this: [link](https://stackoverflow.com/questions/41664409/wait-for-5-seconds) but I don't know how to put the handler into my code. Can you help me out there? – ayanu99 Mar 12 '21 at 13:16
  • new Handler().postDelayed(new Runnable() { @Override public void run() { //call your function here. } }, mInterval); – Muhammad Farhan Arif Mar 12 '21 at 17:13

2 Answers2

0

i am using this code to get location, using FusedLocationProviderClient and its giving almost accurate location upto 5..7 meters

try {
   
        Task<Location> locationResult = mFusedLocationClient.getLastLocation();
        locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
            @Override
            public void onComplete(@NonNull Task<Location> task) {
                if (task.isSuccessful()) {
                  Location  location = task.getResult();
                    if (location != null) {
                        
                        //fo your job
                        
                    } else {
                        Toast.makeText(context, "Please on GPS", Toast.LENGTH_SHORT).show();
                    }
                }
                else {
                    Toast.makeText(context, "error:"+task.getException().getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    
} catch (SecurityException e) {
    Log.e("Exception: %s", e.getMessage(), e);
}
  • Doesn't this simply get the last location without triggering a new location request? As I said, I have another button showing the last know location precisely after having started GoogleMaps once to force the precise location update. I need to have such a precise new location request in my code. – ayanu99 Mar 12 '21 at 17:10
0

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.

ayanu99
  • 63
  • 8