{"record":{"id":"7d9088c52794ebab","repo":"microg/GmsCore","slug":"neither-android-permission-access-coarse-location","errorCode":null,"errorMessage":"Neither android.permission.ACCESS_COARSE_LOCATION nor android.permission.ACCESS_FINE_LOCATION granted.","messagePattern":"Neither android\\.permission\\.ACCESS_COARSE_LOCATION nor android\\.permission\\.ACCESS_FINE_LOCATION granted\\.","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"play-services-maps/core/vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java","lineNumber":518,"sourceCode":"    }\n\n    @Override\n    public void setIndoorEnabled(boolean indoor) throws RemoteException {\n        Log.w(TAG, \"Indoor not yet supported\");\n    }\n\n    @Override\n    public boolean isMyLocationEnabled() throws RemoteException {\n        return false;\n    }\n\n    @Override\n    public void setMyLocationEnabled(boolean myLocation) throws RemoteException {\n        Log.w(TAG, \"MyLocation not yet supported\");\n        boolean hasPermission = ContextCompat.checkSelfPermission(context, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED\n                || ContextCompat.checkSelfPermission(context, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED;\n        if (!hasPermission) {\n            throw new SecurityException(\"Neither \" + ACCESS_COARSE_LOCATION + \" nor \" + ACCESS_FINE_LOCATION + \" granted.\");\n        }\n        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);\n        if (myLocation) {\n            locationManager.requestLocationUpdates(5000, 10, criteria, listener, Looper.getMainLooper());\n        } else {\n            locationManager.removeUpdates(listener);\n        }\n    }\n\n    @Override\n    public boolean isBuildingsEnabled() throws RemoteException {\n        return backendMap.hasBuilding();\n    }\n\n    @Override\n    public void setBuildingsEnabled(boolean buildingsEnabled) throws RemoteException {\n        backendMap.setBuildings(buildingsEnabled);\n    }","sourceCodeStart":500,"sourceCodeEnd":536,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-maps/core/vtm/src/main/java/org/microg/gms/maps/vtm/GoogleMapImpl.java#L500-L536","documentation":"GoogleMapImpl.setMyLocationEnabled mirrors the Google Maps SDK contract: showing the user's location requires a location permission. microG checks for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION at call time and throws a SecurityException when neither is granted. The feature is otherwise not yet implemented in the vtm backend (a warning is logged).","triggerScenarios":"Calling googleMap.setMyLocationEnabled(true) from an app whose manifest lacks the permission or whose runtime permission was not granted (permission denied/revoked or never requested via ActivityCompat.requestPermissions).","commonSituations":"Adding a map with my-location layer while only having manifest permission but no runtime grant; testing on Android 6+ without runtime request; permission revoked by user or by system battery/privacy management.","solutions":["Add <uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/> (and/or ACCESS_COARSE_LOCATION) to the manifest","Request the permission at runtime with ActivityCompat.requestPermissions and check grantResults before calling setMyLocationEnabled","Wrap the call and only enable the my-location layer when ContextCompat.checkSelfPermission returns PERMISSION_GRANTED"],"exampleFix":"// before\ngoogleMap.setMyLocationEnabled(true);\n// after\nif (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {\n    googleMap.setMyLocationEnabled(true);\n} else {\n    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQ_LOC);\n}","handlingStrategy":"try-catch","validationCode":"boolean granted = ContextCompat.checkSelfPermission(ctx, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED\n    || ContextCompat.checkSelfPermission(ctx, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;\nif (granted) googleMap.setMyLocationEnabled(true);","typeGuard":null,"tryCatchPattern":"try { googleMap.setMyLocationEnabled(true); } catch (SecurityException e) { requestRuntimeLocationPermission(); }","preventionTips":["Declare ACCESS_FINE_LOCATION (and/or ACCESS_COARSE_LOCATION) in the manifest","Always request location permission at runtime before enabling the my-location layer","Re-check permission on onResume since the user can revoke it"],"tags":["android","maps","permission","security"],"backgroundTag":"permission-denied","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}