ACCESS_FINE_LOCATION SecurityException despite specifying the permission in the manifest file
Solution 1
The issue was caused by a new feature for Android 6.0.
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
http://developer.android.com/training/permissions/requesting.html
To get around the issue when the permission is not explicitly granted, I had put in a check to wrap location service calls (as per the Google Documentation, slightly modified).
int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
//Execute location service call if user has explicitly granted ACCESS_FINE_LOCATION..
}
The Google Documentation also steps through how to request for the permissions that are needed.
UPDATED 12th Oct 2016
Adding in @Siddharth's update to include a more helpful answer for checkSelfPermission()
//For this example, run the check onResume()
@Override
public void onResume() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, 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.
// PERMISSION_REQUEST_ACCESS_FINE_LOCATION can be any unique int
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_ACCESS_FINE_LOCATION);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} 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
}
}
Solution 2
Extract from Google Documentation. Seems like the most accepted answer on this thread is missing some critical information about the call back of the async checkSelfPermission
.
Please confirm. If not, I'll delete this answer.
// 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.READ_CONTACTS)) {
// 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.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} 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
}
}
gyamana
Updated on July 24, 2022Comments
-
gyamana almost 2 years
My app is attempting to access the device's location and I have included the following in the
AndroidManifest.xml
:<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.app"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <application> <meta-data android:name="com.google.android.gms.version" /> </application> </manifest>
I have implemented the
GoogleApiClient.ConnectionCallbacks
as follows to access the location service:public class BackgroundLocationService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { private static final String TAG = BackgroundLocationService.class.getSimpleName(); private static GoogleApiClient googleApiClient; private static PendingIntent locationCallback; public static int LOCATION_INTERVAL = 10000; public static int FAST_INTERVAL = 5000; @Override public void onConnected(Bundle bundle) { Log.i(TAG, "Connected to Google API"); LocationRequest request = new LocationRequest(); request.setInterval(LOCATION_INTERVAL); request.setFastestInterval(FAST_INTERVAL); request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, request, locationCallback); } @Override public void onConnectionSuspended(int i) { Log.i(TAG, Integer.toString(i)); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.i(TAG, connectionResult.toString()); } }
When I trigger the location service call, the following exception is thrown:
java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. at android.os.Parcel.readException(Parcel.java:1599) at android.os.Parcel.readException(Parcel.java:1552) at com.google.android.gms.location.internal.zzi$zza$zza.zza(Unknown Source) at com.google.android.gms.location.internal.zzk.zza(Unknown Source) at com.google.android.gms.location.internal.zzl.zza(Unknown Source) at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) at com.google.android.gms.location.internal.zzd$7.zza(Unknown Source) at com.google.android.gms.internal.zzlb$zza.zzb(Unknown Source) at com.google.android.gms.internal.zzlf.zza(Unknown Source) at com.google.android.gms.internal.zzlf.zzb(Unknown Source) at com.google.android.gms.internal.zzli.zzb(Unknown Source) at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source) at com.localz.spotzpush.sdk.service.BackgroundLocationService.onConnected(BackgroundLocationService.java:45) at com.google.android.gms.common.internal.zzk.zzh(Unknown Source) at com.google.android.gms.internal.zzlg.zznU(Unknown Source) at com.google.android.gms.internal.zzlg.onConnected(Unknown Source) at com.google.android.gms.internal.zzli$2.onConnected(Unknown Source) at com.google.android.gms.common.internal.zzj$zzg.zzpf(Unknown Source) at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source) at com.google.android.gms.common.internal.zzj$zza.zzt(Unknown Source) at com.google.android.gms.common.internal.zzj$zzc.zzph(Unknown Source) at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I am using an actual device to produce this issue and have been scratching my head on why the exception is thrown.
-
satish123 over 7 yearsI am getting java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations. crash with Target SDK 22 on Android 5.1 (Device is S plus (GiONEE_WBL7511)) Any clues?
-
Siddharth over 7 yearsPlease review my answer and make appropriate corrections. I'll delete my answer if you can make corrections to your answer.
-
gyamana over 7 years@Siddharth, OK, thanks for that, will update my answer now
-
gyamana over 7 yearsAlso, updating Android Studio to the latest version will allow it to automatically check, flag and resolve this issue.
-
Ajay over 7 yearsHow could request permission from service?
-
Jaswanth Manigundan over 6 years@arpitgoyal2008 did you manage to solve this issue ? I am facing similar issues on Galaxy J3 and J3 pro. Strange for a mobile running on Android 5.1