Search code examples
androidgpslocationmanagertargetsdkversion

"location provider requires ACCESS_FINE_LOCATION permission" even if I use runtime request permission


This is so weird. We all know that if <uses-sdk android:targetSdkVersion="23"/> is set to 23+, you must ask for runtime permissions besides declaring <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> in the manifest.

This has been working with no problem for years. Now, The problem is that when I am setting targetSdkVersion to "26", the LocationManager is not working anymore! and throws this error:

"gps" location provider requires ACCESS_FINE_LOCATION permission

The only thing that I change in my app is the targetsdkversion from 23 to 26 and it breaks the app! Any ideas?


Solution

  • Ok, I could fix the problem and I'll explain it here also in case someone else is facing a similar problem. I should add that while the problem is now fixed, it feels like a bug on Android or lack of documentation.

    Because of some internal project reasons, I was requesting for the location permission like this:

    PackageInfo packageInfo = pm.getPackageInfo(_activity.getPackageName(), PackageManager.GET_PERMISSIONS);
    String[] requestedPermissions = null;
    if (packageInfo != null)
    {
        requestedPermissions = packageInfo.requestedPermissions;
    
        if (requestedPermissions.length > 0)
        {
            List<String> requestedPermissionsList = Arrays.asList(requestedPermissions);
            _requestedPermissionsArrayList = new ArrayList<String>();
            _requestedPermissionsArrayList.addAll(requestedPermissionsList);
        }
    }
    
    for(int i=0; i < _requestedPermissionsArrayList.size(); i++)
    {
        if(_requestedPermissionsArrayList.get(i).equals(Manifest.permission.ACCESS_FINE_LOCATION) || // api level 1
                _requestedPermissionsArrayList.get(i).equals(Manifest.permission.ACCESS_COARSE_LOCATION) // api level 1
            )
        {
            isFound = true;
            ActivityCompat.requestPermissions(_activity, new String[]{
                    _requestedPermissionsArrayList.get(i)
            }, ExConsts.MY_PERMISSIONS_REQUEST);
            break;
        }
    }
    

    With this setup, the order of permissions in the manifest mattered! When I had:

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

    it didn't work but when I switched their order, it did work.

    Finally, how did I fix the problem? like below, I mentioned both permission names

    ActivityCompat.requestPermissions(_activity, new String[]{
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
    }
    

    Now, no matter the order of permissions in the manifest, it always worked fine. cheers.