I have an app to get user location with permissions.My target API=25 btw
Once I have given permission that It doesn't ask me for request permission anymore.
I have checked with debug my hasCoarseLocationPermission and hasFineLocationPermission always return 0(GRANTED) after giving permission.
But if I clear the app data asking for permission again(returns -1).But I always want to ask for permission when I open the application(must return -1 not 0).How can i do that?
Thanks in advance.
int hasCoarseLocationPermission=ContextCompat.checkSelfPermission(Kirala3.this, Manifest.permission.ACCESS_COARSE_LOCATION);
int hasFineLocationPermission = ContextCompat.checkSelfPermission(Kirala3.this, Manifest.permission.ACCESS_FINE_LOCATION);
I've tried also with PermissionChecker function but it returns same value(0).
Try with ActivityCompat
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Use this function for checking location permission
public boolean isLocationPermissionEnabled() {
return !(Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED);
}
Asking the user for permissions is not something an app is supposed to do at each launch. Once the app has been granted a permission, it has the permission until it is revoked by the user. What you describe is happening sounds correct:
First launch the app calls checkSelfPermission and gets back PERMISSION_DENIED
The app requests the permission and is granted by the user
Subsequent launches of the app also still call checkSelfPermission (which is exactly what it should do.) Now the returned value is PERMISSION_GRANTED. This is expected. No new permission request from the user is required.
Manually reset the app data and revoke the permissions in the Settings app
Launch the app again and checkSelfPermission returns PERMISSION_DENIED, the app must ask the user for permission again.
You may find this talk helpful: https://youtu.be/WGz-alwVh8A
You may also find this permissions helper library useful: https://github.com/hiqes/andele
Related
On Android 12 devices (API 31),
User has GRANTED both the precise and approximate permissions and app is working fine post that.
When user turns off the device location by going into settings, I see the ACCESS_FINE_LOCATION permission as NOT GRANTED.
When checked by navigating into settings, we see precise location is turned on and location is set to allow all the time. Still the ACCESS_FINE_LOCATION is returned as NOT GRANTED.
In this scenario below code returns false -
override fun hasLocationPermission(): Boolean {
return PermissionChecker.checkSelfPermission(
mContext,
android.Manifest.permission.ACCESS_FINE_LOCATION
) === PermissionChecker.PERMISSION_GRANTED
}
So if user turns off device location then FORGROUND LOCATION PERMISSION IS NOT GRANTED. is this the expected behaviour in Android 12?
Please assist.
I think that PermissionChecker returns PERMISSION_DENIED_APP_OP. PermissionChecker can return three result: PERMISSION_DENIED, PERMISSION_GRANTED or PERMISSION_DENIED_APP_OP. If you want result PERMISSION_GRANTED, try to use ContextCompat.
override fun hasLocationPermission(): Boolean {
return ContextCompat.checkSelfPermission(
mContext,
android.Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED }
When we ask permission from the user on his phone, is there a way we can inform the OS not to ask this permission again? No matter what the user's response is.
If the program does not "desperately" require the permission, you can use SharedPreferences and store a variable called firstTime withe boolean value of true.
Then check in the onCreate method for that variable. if it is true, ask the permission then set the value to false and save it. Then when the user will rerun the application, it won't be the "FirstTime" so he won't be prompted with the permission.
SharedPreferences pref = this.getSharedPreferences("PACKAGE.NAME",MODE_PRIVATE);
Boolean firstTime = pref.getBoolean("firstTime",true);
if(firstTime){
//Ask for permissions here
pref.edit().putBoolean("firstTime",false).apply();
}
No, sorry. You would need to keep track of whether you asked the user for permissions, then use that information to determine whether or not to ask in the future.
When you ask the permission in any way like in the following, in the dialog that would be open to ask for permission there is a check box that by checking it, OS would not ask you for that permission any more:
if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_WRITE_EXTERNAL_STORAGE);
}
}
I am developing an app that allows a user to connect to a specific wifi network using the google vision api to scan a QR code containing an ssid. To scan for wifi networks I need to request the user to grant the location permission. This all works fine if i go to the settings and manually enable the Location permission but when requesting the permission at run-time, the user taps enable then a second dialog pops up, Screen Overlay Detected which requires a context switch to enable the Screen Overlay permission. I am not drawing over other apps and when i manually enable the location permission there is no problems. So why is this permission dialog popping up?
As I am not sure why Android is asking for this permission i am not sure what code to post. i have included the request for the 3 required permission for the change network request.
final int permissionCheck = ContextCompat.checkSelfPermission(mActivity, Manifest.permission.CAMERA);
final int locationPermissionCheck = ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION);
final int wifiPermissionCheck = ContextCompat.checkSelfPermission(mActivity, Manifest.permission.CHANGE_WIFI_STATE);
final int granted = PackageManager.PERMISSION_GRANTED;
if ((permissionCheck != granted) || (locationPermissionCheck != granted) || (wifiPermissionCheck != granted)) {
ActivityCompat.requestPermissions(mActivity, new String[]{
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CHANGE_WIFI_STATE
}, 0);
} else {
cameraSource.start(cameraView.getHolder());
}
Update
Turns out its not just the location permission that trips it up. Any permission request is experiencing the same behaviour.
It may be some libraries you are using in your that requires screen overlay permission. Can you check the libraries you are using in your and the permission they require.
I have request the permission in android version 6.0 - Marshmallow,But it still return empty list when using getScanResults().
private boolean checkPermission() {
List<String> permissionsList = new ArrayList<String>();
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_FINE_LOCATION);
}
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (permissionsList.size() > 0) {
ActivityCompat.requestPermissions((Activity) mContext, permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return false;
}
return true;
}
After request permission, then in the onRequestPermissionsResult method,I have get the permission of ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION, But I still can not the scan result
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
if (permissions.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED ||
(permissions.length == 2 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED)){
List<ScanResult> scanResults = mWifi.getScanResults();
//list is still empty
}
else {
// Permission Denied
Toast.makeText(mContext, getString(R.string.permission_deny), Toast.LENGTH_LONG).show();
}
break;
}
}
Is this a bug of android M?
You still need to enable WIFI after you request the permission. So in short, you have to do this in sequence for scanning the perimeter:
Request the necessary permissions (ACCESS_WIFI_STATE, CHANGE_WIFI_STATE, ACCESS_COARSE_LOCATION). Additionally, on MM you need to request this at run-time, as you stated.
Enable WIFI with WifiManager#setWifiEnabled(true);
You don't have to enable location access programatically that I know off. But read the note below.
You have to register a BrodcastReceiver for SCAN_RESULTS_AVAILABLE_ACTION. This is where you get the signal that the scans are ready. Doesn't matter if you register through AndroidManifest or dynamically at run-time, as long as it's done before the next step.
You have to WifiManager#startScan() in order to request exactly ONE update for network scans. If you want more, set up a timer/timertask (recommended) or reschedule when you receive the previous one (which might never come)
Only on the BroadcastReceiver onReceive will you be able to call WifiManager#getScanResults() with plausible results.
Note: On some phones (Moto X 2014), I noticed you need basic location enabled to get any results, which only the user (system UI) seems to be able to do trigger on/off. If the user has location completely off, I can't seem to get a non-empty result list, even though the system UI can. This is likely due to Marshmallow needs to have location for Bluetooth and WiFi scans in user apps, and a bad implementation by Motorola, or a defect already fixed in latest Marshmallow bug tracker but not in Motorola's latest OTA, because this doesn't happen in a Nexus 5 or a Galaxy S6.
on nexus 5, with M update, it appears to me I also need to have GPS location turned on to get this working.
Maybe it cause by android M's runtime permission management,you can set targetSdkVersion 19(less than 21 or 23) to try again. It works for me
In Android Marshmallow 6.0.1 go to Settings > Connections and hold down Location. There click on Location method and you will see three options:
High accuracy: uses GPS, Wi-Fi and mobile networks.
Battery saving: uses Wi-Fi and mobile networks.
Device only: uses GPS.
Select Battery saving in order to get Wi-Fi scan results without enabling GPS.
The permission is requested when needed at run-time. Note that it is NOT:
Settings -> Location
It is checking:
Settings -> Applications -> (YOUR APP) -> Permissions
That is where the more granular run-time permission must be set. It must be set for each application as of version 6.
I'm testing denial of permission to an application and I'm seeing that when asking for the state of the permission it returns granted instead of denied.
I'm checking state of permissions according to Google's Guide:
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.CAMERA)) {
// 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(getActivity(),
new String[]{Manifest.permission.CAMERA},
PERMISSIONS_REQUEST_TAKE_PHOTO);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
Here is what it actually returns in the first if:
State "0" means PackageManager.PERMISSION_GRANTED
This is generating a java.lang.RuntimeException: Fail to connect to camera service error.
DEVICE IS A NEXUS 5X
Best regards.
Quotig #CommonsWare:
You're supposed to get PERMISSION_GRANTED for any targetSdkVersion below 23, even if the user toggled off that permission group in Settings. I suggest that you uninstall the app completely, set your targetSdkVersion to 23, and try it again.
This was the solution.
(This answer will be marked correct temporarily until commenter posts an answer)