What would be the proper way to check permission and ask if not granted.
And disable some entry point component if permission is not granted.
It is easy at initial point but when app permission is changed anytime the app should take care of it.
I tried to check permission every time app rendered and used useEffect to listen to permission states but it becomes messy.
So now I am changing the functional components to class component to acces lifecycle easily.
I am avoiding the RN modules like redux as RN app size are greater.
I have also created some components which will appear on the basis of
granted,
denied,
never ask again
So if permission is granted or denied, It is simple to manage that but if permission is 'never ask again' then app will show the suggestion which will open the setting of the app.
After that user would come back to app and app should aware of the permission changes
How should we manage these permissions and states?
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.
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 know, with Android Marshmallow, we have to ask permissions every time we need a functionality that require a permission.
I do this for new App, but for old BIG App is more complicated.
For old BIG App, I ask all permissions in "MainActivity".
So, my app is started and shows a Map Fragment.
I ask for Location Permission with no problem. The user agrees.
The user puts it in background, goes in the App Settings and denies permission.
Then he puts the App in foreground: App crashes!!
I know, there is a problem using Map Fragment.
But the App is too BIG to analyze every single permission.
I need the FAST solution: PERMISSION CHANGE ---> RESTART APP!!!
And this is what GoogleMaps does!
I started GoogleMaps, and put it in background.
GoogleMaps App permissions, the first difference:
in my App, if I denied a permission, I haven't this message showing for Google Maps:
Permission denied
After that, if I put GoogleMaps in foreground, the App restart with no problem:
GoogleMaps restart
I need this for my app. Can someone help me?!?!?!?
Thanks a lot!!
When permissions are revoked, your app is killed and restarted. Look on the logcat when you revoke permission with your application in background. You will see :
I/ActivityManager(572): Killing 13896:com.your.app/uxxxx (): permissions revoked
So you need to only check permissions in your class "myApplication extends Application" in the onCreate() function.
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.