DontPanic
DontPanic

Reputation: 2406

Permission: Call requires permission which may be rejected by user

Upon compilation under Android Studio, I get the warning as specified in the title of this post. I tried to get GPS updates with the following code:

    try {
        LocMgr = (LocationManager)getSystemService( LOCATION_SERVICE );
        LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
        //LocMgr.addNmeaListener( this );   // NMEA
    }
    catch(Exception e) {
        UI.warningBox( this, "GPS appears to be either absent or disabled" );
    }

Strangely, my app still works just fine without any run-time request for permission. I did however request the permission in the manifest.

    uses-permission  android:name="android.permission.ACCESS_FINE_LOCATION"
    uses-permission  android:name="android.permission.ACCESS_COARSE_LOCATION"

I'm not unhappy, but I was expecting failure or at least a security exception.

Why is Android Studio being so (unexpectedly) forgiving?

By the way, my module's gradle script includes

    defaultConfig {
    applicationId "MY_APP_ID"
    minSdkVersion 11
    targetSdkVersion 26
    }

Upvotes: 1

Views: 758

Answers (2)

guipivoto
guipivoto

Reputation: 18677

Your app is not requesting permission in runtime because you did not added the code to. Also, run-time permission was added on recent Android (I guess started on Android M).

So, in previous Android versions, your app will work fine since you just need to add the permission to the manifest.

On new versions, you must additionally request the permission at the runtime.. Lack-of-permission does not always lead to a crash.. They can only genarated a warning on logs etc.

For any case, to get rid of that warning, you must request the permission at runtime. Below, you can find a small example:

public class MainActivity extends AppCompatActivity implements LocationListener {

    private final static int LOCATION_PERMISSION_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ....

        try {
            LocMgr = (LocationManager) getSystemService(LOCATION_SERVICE);

            if (ActivityCompat.checkSelfPermission(this, permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED 
                  && ActivityCompat.checkSelfPermission(this, permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // Missing both permissions. User didn't accept them yet. Request
                ActivityCompat.requestPermissions(this, new String[] {permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_CODE);
            } else {
                // Have permissions. Don't need to request. Just request location
                LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
            }
        } catch(Exception e) {
            UI.warningBox( this, "GPS appears to be either absent or disabled" );
        }

        ....
    }

    @Override
    public void onRequestPermissionsResult(final int requestCode,
            @NonNull final String[] permissions,
            @NonNull final int[] grantResults) {
        if(requestCode == LOCATION_PERMISSION_CODE) {
            if(grantResults.length > 1
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED /* ACCESS_FINE_LOCATION */
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED /* ACCESS_COARSE_LOCATION */) {
                // User accepted both permissions. request location updates
                LocMgr.requestLocationUpdates( K.GPS_PROVIDER, 0, 0, this );
            }
        }
    }
}

Upvotes: 0

Karan Harsh Wardhan
Karan Harsh Wardhan

Reputation: 1126

What version of android are you using to run your app? prior to marshmallow(api level 23) you could access lots of services like LocationService without actually asking for permission from the user.

you can even use wifi and bluetooth without asking for permission. it was the wild west of permissions back then. this has changed since then and since your highest level api could potentially ask for permissions(which you're not handling), that's why you're getting the warning

also fyi if you have access to google services, you should use fusedlocationprovider instead, locationservice doesn't give valid results without creating a service to continuously poll it.

Upvotes: 1

Related Questions