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.
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).
Since Android 6 permissions can be requested on runtime. The user has the chance to grant or revoke permissions. He is always asked by the UI in form of a dialog popping up.
Is it somehow possible to grant permissions via voice input? I searched by myself but didn't find any approach for that. Is there any information to find about this topic? At least maybe some research how to make that possible maybe in future Android versions?
It would be great to find any kind of useful information about. that topic
I do not think so. It would not be safe, the user could accuse the application after capturing his audio without permission, for example.
You must EXPLICITLY allow anything (even acess the microphone to capture anything) that involves application access. So it's complicated for you to define something as explicit when using voice. The user may claim that he was only in a normal conversation when the application was granted permissions, and this can cause problems ...
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.
with Androids new permission system, I was wondering how to implement it right. The tutorials about how and when to use the permissions seem to be pretty clear. However, I don't know who requests the permissions and where to request them.
So, basically my question is: should the Activity, who starts another Activity request the permission beforehand or should the Activity which requires the permission place the request?
If the Activity which requires the permission should request for it, should I call requestForPermission inside onCreate or in onStart?
Though it seems to be very simple questions, I haven't found any hints in the documentation.
Thanks.
should the Activity, who starts another Activity request the permission beforehand or should the Activity which requires the permission place the request?
That is up to you. The main guidance is that there should be a clear tie from something the user does to your request for permissions:
If your app needs certain permissions to do anything meaningful, ask for them when your app starts up, perhaps after any sort of "welcome" presentation to advise them about why you need the permissions.
If your app needs certain permissions to do something based on the user performing some in-app action, like tapping on an action bar item or ListView row, ask for the permission when the user performs that action.
Asking for permissions at semi-random points in the app will simply lead to user confusion ("what did I do? why is it asking me this? and why are these questions appearing in an Stack Overflow answer?!?").
If your app can't function properly without a particular permission might be good to have a welcome permission flow where you explain why need the permissions and ask for the grants. For example : Google maps and location permission
If some specific parts of the app need a separate permission you can call the permission check just before doing a method call that needs permission. In this case you can create a wrapper for your function that needs contact permission and always call that wrapper instead of the actual method. For example : Google maps and microphone permission when you try to use the search with voice functionality
More details http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en
also check out https://github.com/permissions-dispatcher/PermissionsDispatcher could reduce a lot of permission code.
When ever your X task struck due to some "Y" permission then only ask for permission. There is no point of asking in onCreate or onStart method.
if you ask for "Y" permission at the start of Activity then there is no difference between Android M and below model. Exploit the beauty of Android M. for example if your require storage permission for creating a temp it's better make a temp file in App internal area i.e /data/data/your package name/files/ rather than asking for storage permission to users. Overall my point is exploit these options as much as you before it become necessary condition to ask for "Y" permission.
Regarding Activity concern , your task must be running be over some fragment or activity let that activity handle the onRequestPermission results.
I'm looking into porting some existing code to take Android M's new way of dealing with permissions into consideration. However the permission API needs to have an activity associated with it (for example the requestPermissions() method's first parameter is an activity).
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
Is it possible for the service to create a dummy invisible activity just for use with the permissions API? (if its possible I don't like the thought of doing that anyway though).
Or suppose its not a service but a model class that needs to perform a permissions check, in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API. Or potentially lots of code might have to migrate from model code into Activity code.
Any thoughts on how to migrate non activity based code that needs to check/prompt for permissions over to Android 6.0?
Update: I left out an important piece of information - this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time and run in the background. Therefore the usual situation of a user being prompted for permission when they launch the app or later (and there therefore being an activity at that point) does not necessarily apply.
So how should a service that needs to check if a permissions has been granted and request for permissions use this new API if the service doesn't have an activity?
There is almost always an activity, except for pre-installed apps and plugins for other apps. Otherwise, your service is unlikely to ever run, as nothing will have used an explicit Intent to start up one of your app's components, so it will remain in the stopped state.
For the ~99.9% of Android apps that have an activity already, if the permissions are needed for the whole operation of the app, request them on first run. As Snild Dolkow notes, if the user later revokes the permission through Settings, you can detect that without an activity, then use other UI options (e.g., Notification, app widget) to let the user know that operation is suspended until they grant you the permissions again, which they would then do through your activity.
Is it possible for the service to create a dummy invisible activity just for use with the permissions API?
Presumably you can have a Theme.NoDisplay activity use requestPermissions(). However, from the user's standpoint, it will not make much sense, unless there's some alternative UI (app widget?) that they are interacting with. Popping up a permission dialog out of nowhere is unlikely to make you popular.
UPDATE 2019-06-15: Note that Android Q bans services popping up activities frmo the background. Please use a notification instead.
in MVC a model shouldn't have any knowledge of the Vs and Cs and yet now either it has to in order to know which Activity to use with the permission API
Do not touch the models until you have requested the permission, and gracefully fail if the permission is revoked. You already have to gracefully fail in other circumstances (out of disk space, no Internet connection, etc.), so a revoked permission should be handled in much the same way.
using this new 6.0 API seems like an recipe for bad design and tight coupling
You are welcome to your opinion. Based on what I have read, the Android engineers believe that asking the user for permissions is part of the user experience and is best handled at the UI layer as a result.
Again: the vast majority of Android apps will not have a problem with this, as they have a user interface. Apps that do not have a user interface and need dangerous permissions are in for some amount of rework.
this is code that is pre-installed (our company provides code that device manufacture's place in rom) and often may be run at device boot time
First, please understand that this is so far from normal that you can't even see normal from where you are due to the curvature of the Earth. :-) You can't really complain that Google did not optimize this particular scenario.
As I understand it, even system apps should be asking for runtime permissions. The Camera app did, for example, on the 6.0 preview. That being said, there's gotta be some database on the device somewhere that is tracking what has been granted, and presumably there is some way to pre-populate it. However, the user could still revoke it from Settings, presumably. But, the manufacturer could pull some stunts (e.g., messing with the Settings app) to possibly even preclude that scenario. I'd be looking in the same area as "how do I get it so my app cannot be force-stopped?" that device manufacturers can do.
Your alternatives would be to get rid of the dangerous permissions or to migrate your app off the SDK and into a standard Linux binary that would be run as part of the boot process and be put into a Linux user group that has access to the stuff that you need.
Ask for it when the user enables whatever feature your service provides. They'll be in one of your activities at the time. Yes, it means that your activities need knowledge of what permissions your services will require.
The service can always check for the permission by itself, though, since checkSelfPermission() is available in all Context instances. So you don't need an activity for that.
I guess an alternative would be to have your service post a notification saying "feature X requires you to approve more permissions". Actually, that may be a good idea regardless, in case the user goes into settings and revokes any permissions after the fact. That notification would then take the user to some activity with an "enable feature X" button/checkbox -- ask for the permission when that is selected.
You can send a notification. Look this library to manage the permissions: permission library