I'm requesting the Manifest.permission.USE_SIP permission. The strange thing is that even though it seems to be considered a dangerous permission, when I request it it seems to be already given so no popup appears and neither does it appear as a switch under Settings->Permission.
And another strange thing is that it seems there's another additional permission:
which is the CONFIGURE_SIP
which I am indeed specifying in the manifest that I need but that one's not a dangerous permission, so why is it in the list under Settings?
So, I figured it out (at least the first part, the important part). I was requesting multiple permissions at a time and before requesting the USE_SIP one I was requesting and granting the REA_PHONE_STATE permission. They both are part of the large group of permissions PHONE. Apparently, and this is what I did not know, is that once a permission group item receives the OK from the user, then all of its items are fine.
Now ... I still can't figure out why the CONFIGURE_SIP permission is visible under Settings, but I've noticed that on 7.0.0 it's not being displayed ... so in case anyone wants to open a question on that, be my guest.
Related
I've set my app to target AP 29 and removed requestLegacyExternalStorage=true from manifest.
Now I'm checking if the user has this permission and if result is denied I request for permission.
My problem is that the request for permission is returning Granted without showing the prompt... I know the flow is working since I'm able to read the GPS location from picture after being granted.
I see permission status = Denied and as soon as I explicitly request this permission, it returns Granted without any user interaction.
Eveything looks OK but I'm confused about not seeing the prompt... is this expected? I saw this permission qualifies as "Dangerous" so I was expecting a prompt. I'm testing on a Android 10 device.
I'm not showing any code since the project is Xamarin and the permission logic is handled through a third party library, don't think my code will help as the platform logic to request the permission is hidden by the component.
From
Android 10: fetch the gallery via MediaStore with location information :
This requires holding the ACCESS_MEDIA_LOCATION permission. Note, this permission is not "user visible in the settings UI" (source), which means the user won't see a popup asking for permission, even though it is a runtime permission. This means you have to ask for permission during runtime (in contrast to just the manifest file) but the user won't have to consent to it. Adding this here because you might be wondering why no extra UI popups are shown.
I'm still getting my head around the logic though. I'm in favour of the user being asked for permission but I don't understand why it should be necessary to "request" it if the user doesn't actually grant permission.
I was able to reproduce the issue in a simpler app. I have posted a slightly different question with code snippets.
This is an answer by HilaryN that I believe should not have been deleted (I removed the off-topic bits).
I couldn't find any information about what happens when the user disables an app's permission while the app is running.
Is the application re-initilized?
I saw that in some apps if a Dialog or BottomSheet is open while I disable the permission, the dialog is no longer displayed when I return to the app.
Can anyone explain what happens in-detail when a permission is denied at runtime? Or does anyone have some useful links for me?
I would be especially interested in which lifecycle events are called when returning to the app.
When a previously granted permission is revoked through settings, the app is force stopped. You can see this by watching your app in the debugger. The app process is marked DEAD as soon as the permission is revoked.
Returning to the app will launch it from the main activity. I've never really looked into why this happens, but I assume it's because when a granted permission is revoked, the user could be deep into the app at a place where it is assumed the permission is granted. When the permission is revoked, there's no way to know if the screen they are currently in is even valid anymore.
Upon returning to the app, the app's state is restored and your current activity will be restarted, similar to a configuration change. If the activity you are in assumes a certain permission is granted, you should probably check that permission again in onCreate() to make sure you have it.
Simply put, That depends on what the app is trying to do when it needs permission.
For example: If we live in a country that requires you to be an adult to watch any video on YouTube, nothing will work with Location permissions denied
Another example: If you want to take photos using your phone via an app, the Camera permission should be permitted.
Under some circumstances, just part functions of app can not be used, but at an Extreme case, app would throw Security Exception and crash.
According to your point :
I saw that in some apps if a Dialog or BottomSheet is open while I
disable the permission, the dialog is no longer displayed when I
return to the app.
There is no lifecycle callback about what you do once permission is denied, but there's method on ActivityCompat which gives you flag if you want to show your own Dialog/BottomSheet
So, you can call shouldShowRequestPermissionRationale() method from ActivityCompat & make your own logic work when it's true.
shouldShowRequestPermissionRationale :
Gets whether you should show UI with rationale for requesting a permission. You should do this only if you do not have the permission and the context in which the permission is requested does not clearly communicate to the user what would be the benefit from granting this permission.
For example,
if you write a camera app, requesting the camera permission would be expected by the user and no rationale for why it is requested is needed.
If however, the app needs location for tagging photos then a non-tech savvy user may wonder how location is related to taking photos. In this case you may choose to show UI with rationale of requesting this permission.
While disabling permission for first time will give you callback in onRequestPermissionResult() method.
As the guide from google states out, there are normal, dangerous and special permissions.
Dangerous are, as far as I understand, disabled as default (is this true?).
If an app declares that it needs a dangerous permission, the user has to explicitly grant the permission to the app.
Does this infect also updates or only new installs?
And what exactly is the difference between the dangerous permission and
the special permissions?
Android says for special permissions:
Special Permissions
There are a couple of permissions that don't behave like normal and dangerous permissions. SYSTEM_ALERT_WINDOW and WRITE_SETTINGS are particularly sensitive, so most apps should not use them. If an app needs one of these permissions, it must declare the permission in the manifest, and send an intent requesting the user's authorization. The system responds to the intent by showing a detailed management screen to the user.
Is that not the same like the quote above? I do not get the difference.
Thanks!
System permissions are divided into two categories, normal and dangerous:
Normal permissions do not directly risk the user's privacy. If your
app lists a normal permission in its manifest, the system grants the
permission automatically.
Dangerous permissions can give the app access to the user's
confidential data. If your app lists a normal permission in its
manifest, the system grants the permission automatically. If you
list a dangerous permission, the user has to explicitly give
approval to your app.
Ques : Dangerous are, as far as I understand, disabled as default (is this true?).
Ans : Yes Dangerous permissions will be disabled by default.
Ques : Does this infect also updates or only new installs?
Ans : There are Two cases
Case 1 : App Targeting & running on API Level 23
If your app is targeting API Level 23, then all the permission which are defined in the Android Manifest will now ask for a permission when they need it.
For example, instead of giving an app access to your camera when you install it, you’ll be prompted the first time the app wants to access your camera.
Case 2 : App Designed for Older Version
Older Android apps automatically get these permissions when you install them, but you can revoke any permission you want from Settings >> Apps >> App >>App Info >> Permissions.
http://developer.android.com/training/permissions/requesting.html
Dangerous
Basically Google decided to mark some permissions dangerous (see full list here). Those permissions need to be requested actively if you want to use them, so you can't just put them in the manifest and expect everything to work, it wont. But if the user gives access once, you can use that permission for the remainder of the applications life (unless the user goes in and clicks it off inside settings).
The request will open a dialog on top of your app where the user can decide if you are allowed the permission.
Special
Special are like dangerous, except even harder to use. In order to use special you have to start an intent requesting the permission so the user goes to a Google defined activity that manages everything.
This is how it works for apps targeting Android 6.0 and onward.
I have got this really weird behaviour.
After adding the permissions at runtime for my app, I was checking and testing all cases.
I have the request code in my MainActivity.
So, after I set Never Ask Again and deny the giving permission for ACCESS_FINE_LOCATION, if I press the menu button and then restart the app (the app will call onResume of MainActivity I guess), then the screen is black except a rectangle part in the middle of the screen which varies in size. (Is not the AlertDialog size)
Here some screenshots:
Normal screen
After press menu and then open again can be that it opens with the normal state or with these states:
Or
This is quite weird, anybody had this before?
Thanks for your answers!
Without seeing the code, it's hard to give a very accurate answer.
When requesting permissions, if the user selected 'never ask again', the request permissions response will be denied. I'm GUESSING (due to lack of code) that your app relies on the granted permission to continue loading the UI and executing more code, which it won't do if permission is denied. You need to handle all possible responses when requesting runtime permissions.
if permission is granted: good to go
if permission is denied: check if you should show the permission rationale. This means you display a message to the user explaining why you need the permission.
if shouldShowRationale is true: it means 'never ask again' was NOT checked. Display the message, then ask for permission again.
if should show Rationale is false: it means 'never ask again' was checked and you should probably direct the user to the app settings to turn the permission on if it's required.
The Android M Preview docs shows us how to check and request permissions with the new permissions model. In the chart below that it shows us a group of Permission Groups and their associated Permissions.
When I try to to checkSelfPermission with a permission_group (ie Manifest.permission_group.CAMERA) on first start, predictably I get PackageManager.PERMISSION_DENIED.
Then try to requestPermissions for that same permission_group and i don't get any type of dialog to pop up. 'onRequestPermissionsResult' returns immediately with -1.
When i try the same sequence with Manifest.permission.Camera - things seem to work as normal. But for a simple app that I'm making, I need to record video with audio, and requesting the two separate permissions, CAMERA and MICROPHONE (aka RECORD_AUDIO) seems like poor design.
The question: Is checkSelfPermission and requestPermission supposed to work with Manifest.permission.* and Manifest.permission_group.* but there's a bug that I should file since it won't show request? Or was this intentional design?
*Note - I understand that I can create a requestPermissions(String[], int) string array with multiple permissions in it myself, but id still have plenty of if statements to check the combinations of permissions i need and to request them as a group, when i should only need to request a permission_group
When I try to to checkSelfPermission with a permission_group (ie Manifest.permission_group.CAMERA) on first start, predictably I get PackageManager.PERMISSION_DENIED.
That is because checkSelfPermission() checks permissions, not permission groups.
Then try to requestPermissions for that same permission_group and i don't get any type of dialog to pop up. 'onRequestPermissionsResult' returns immediately with -1.
That is because requestPermissions() works with permissions, not permission groups.
Is checkSelfPermission and requestPermission supposed to work with Manifest.permission.*
Yes.
and Manifest.permission_group.*
No.
Or was this intentional design?
Presumably, yes. At least on the checkSelfPermission(), it layers atop other pre-existing methods that date back to API Level 1 and work on permissions, not permission groups.
when i should only need to request a permission_group
You are making assumptions about the future of Android that may not be accurate. Right now, pre-M, permission groups are not especially important, and permissions are what matter. In M, permission groups climb in importance, as that is what M uses in its presentation to end users regarding what the user can control. However, versions of Android after that might offer finer granularity on this, whether to individual users or to enterprises via policies, and that would likely go back to permissions.
The API suggests that Google is leaving the door open for those sorts of moves. In effect, the permission group stuff is a UX decision, more so than a technical one.