35

In the android manifest file I have added the below permissions for gps to access the location

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

I am fecthing Location Updates as below using Location Manager Class

 private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
 private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
 locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    MIN_TIME_BW_UPDATES,
                    MIN_DISTANCE_CHANGE_FOR_UPDATES, 
                    this
                );

But the above line is giving an exception stating

"gps" location provider requires ACCESS_FINE_LOCATION permission

This thing only happens with the targetSDKVersion 23(i.e with android 6.0) and i have also tested in android 5.1 which works fine.

Please Help!!.Thanks in Advance.

bhanu.cs
  • 1,345
  • 1
  • 11
  • 25

4 Answers4

68

Since 6.0 some permissions are considered as "dangerous" (FINE_LOCATION is one of them).

To protect the user, they have to be authorized at runtime, so the user know if it's related to his action.

To do this :

 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

It will show a DialogBox in which user will choose wether he autorize your app to use location or not.

Then get the user answer by using this function :

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
        return;
        }
            // other 'case' lines to check for other
            // permissions this app might request
    }
}

If the user accept it once, then your app will remember it and you won't need to send this DialogBox anymore. Note that the user could disable it later if he decided to. Then before requesting the location, you would have to test if the permission is still granted :

public boolean checkLocationPermission()
{
    String permission = "android.permission.ACCESS_FINE_LOCATION";
    int res = this.checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);
}

It's all explained on Android documentation (onRequestPermissionsResult from there too): http://developer.android.com/training/permissions/requesting.html

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Sebastien FERRAND
  • 2,110
  • 2
  • 30
  • 62
  • Nice and detailed answer, great! Will try that out as well, haven't yet checked with Android Marshmellow. This breaks compatibility to a lot of apps I suppose, so they won't roll out quickly on devices using the previous version? – RookieGuy Nov 23 '15 at 10:12
  • I didn't think about that myself as I tried it recently on an app i'm developping :) I suppose the dangerous permissions that have been granted before this update will remain granted, even if they were granted on install. – Sebastien FERRAND Nov 23 '15 at 10:30
  • Note that the user can now decide to disable the permission in the application android settings. – Sebastien FERRAND Nov 23 '15 at 10:36
  • Thank you for the answer. but i just want to add, the Manifest.permission *should be careful to choose the Manifest. Because on my android studio, I got 3 or more Manifest file. – Andrew Indayang May 13 '16 at 00:25
  • Why asking for ACCESS_COARSE_LOCATION is not needed? – DAVIDBALAS1 Aug 17 '16 at 16:47
  • Might be needed indeed, the point was mostly to point out the new permission system. – Sebastien FERRAND Aug 31 '16 at 04:20
6

Try this code

private void marshmallowGPSPremissionCheck() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && getActivity().checkSelfPermission(
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && getActivity().checkSelfPermission(
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSION_LOCATION);
        } else {
            //   gps functions.
        }
    }

add this also..................

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults) {
        if (requestCode == MY_PERMISSION_LOCATION
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //  gps functionality
        }
    }
Nivedh
  • 971
  • 1
  • 8
  • 19
  • 1
    What is getActivity() here??What is actually happening ??Could you please explain – bhanu.cs Nov 23 '15 at 07:20
  • This guy's code must be in a fragment, or something similar. You can use getActivity() to get the Context, in case you are in a class that extends Fragment and not Activity. – Fustigador Nov 23 '15 at 07:43
  • Does this code work for you? If you are using this in activity remove the getActivity(). This code actually checks the permission of location during run time. – Nivedh Nov 23 '15 at 08:11
0

We have some changes in android permissions since version 6. You have to agree the permissions on time of using them, not when installing app. If you use buildtools version 23 some problems may occur. Check this link to understand. Go to the device settings>apps and select your app then accept permissions manually and check if your problem is solved.

0

I've experienced this problem recently as well. In Android 6.0 you need to explicitly ask for the permissions you need when you use them in the app. If you don't, the location permission is automatically denied.

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_FINE_LOCATION);

            // MY_PERMISSIONS_REQUEST_FINE_LOCATION is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }

More info here: http://developer.android.com/training/permissions/requesting.html

Kelly
  • 13
  • 3