Search code examples
androidandroid-permissionsandroid-gps

How to gain permission to get GPS location in Android


I am new to Android and in my current project I am trying to retrieve location using GPS. The code for obtaining the location is in a separate non-activity class, because the fragment where I display the coordinates is crammed.

I have tried to use the guidelines from developer.android.com but I can't get any permission prompt, and when I press the button in the fragment, I only get the default 0-values for latitude and longitude.

I have provided the permissions in the manifest:

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

The GPS locator class:

public class LocationProvider implements ActivityCompat.OnRequestPermissionsResultCallback {
    private static final int PERMISSION_REQUEST_LOCATION = 1;
    private Activity activity;

    Location gps_loc;
    Location final_loc;
    double longitude;
    double latitude;
    private LocationManager locationManager;

    public LocationProvider(Activity activity) {
        this.activity =activity;
        locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_LOCATION) {
            // Request for permission.
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getLocation();
            } else {
                requestLocationPermission();
            }
        }
    }

    private void getLocation() {
        // Check if the permission has been granted
        if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (gps_loc != null) {
                Log.v("Loc_provider",gps_loc.toString());
                final_loc = gps_loc;
                latitude = final_loc.getLatitude();
                longitude = final_loc.getLongitude();
            }
        } else {
            requestLocationPermission();
        }
    }


    private void requestLocationPermission() {
            ActivityCompat.requestPermissions(activity,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_LOCATION);
        }


    public String getCoordinates() {
        return latitude + " "+ longitude;
    }
}

The code in the fragment:

FloatingActionButton fab=view.findViewById(R.id.floatingActionButton);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                locProvider=new LocationProvider(requireActivity());
                gpsCoordinates.setText(locProvider.getCoordinates());
            }
        });

Tips and solutions for fixing the code are most welcome.

UPDATE 1: I moved the code in the fragment instead, so that it looks like below:

fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!checkIfAlreadyhavePermission()) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                } else {
                    gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    gpsCoordinates.setText(getCoordinates());
                    }
                }
        });

private String getCoordinates() {
        if (gps_loc != null) {
            Log.v("Loc_provider", gps_loc.toString());
            final_loc = gps_loc;
            latitude = gps_loc.getLatitude();
            longitude = gps_loc.getLongitude();
        }
        return latitude + " " + longitude;
    }

    private boolean checkIfAlreadyhavePermission() {
        int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
        return result == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //Log.v("Grant_Results", String.valueOf(grantResults[0]));
                    Toast.makeText(getActivity(), "permission granted", Toast.LENGTH_LONG).show();
                    gpsCoordinates.setText(getCoordinates());
                    } else {
                       Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
                    }
                break;
                }
            }
    }

I now get the permission prompt, but the location still doesn't update (I get 0).


Solution

  • Fixed by implementing LocationListener in Fragment and then adding

    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 1, this);
    

    in onRequestPermissionsResult().