joshuapinter / react-native-unified-contacts

Your best friend when working with the latest and greatest Contacts Framework in iOS 9+ in React Native.
MIT License
158 stars 56 forks source link

[Android] alreadyRequestedAccessToContacts #73

Closed paintedbicycle closed 6 years ago

paintedbicycle commented 6 years ago

Hey,

So I've been trying to get the alreadyRequestedAccessToContacts method working on Android and I'm starting to wonder if it's actually possible. I've read a lot and I've tried to dive into the code from other react native contacts libraries that do similar things. Many of them have functions that appear to indeed return an undefined state (not just granted or denied) which could be used in our case. But when I start to audit their code, I see where it's coming from in iOS but in Android there doesn't seem to be that third case.

In my app, I have three states:

I've read stuff like this https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en that nicely walks through the whole process, but again skips the already requested mode. So do the official docs https://developer.android.com/training/permissions/requesting#java

I don't think it's possible to create those 3 different states without this "undefined" state for permissions. I could probably save something to the db myself, but this seems like something a contacts library should handle, no?

Now - React Native Permissions https://github.com/yonahforst/react-native-permissions again lists 4 different permissions states (the 3 above plus restricted) and they seem to have a decent pattern: https://github.com/yonahforst/react-native-permissions/blob/master/lib/permissions.android.js#L56

Is that something that could work here?

joshuapinter commented 6 years ago

Fixed in 84b6ce31552d741c3c93c6cf0c602e0ec76adcb4!

This is an interesting one, because Android handles things a little differently than iOS.

With Android, you can request for the same permission again if the User deny’s the first time. The second request will show the same dialog box but will also have a checkbox that says “Don’t ask again.”

If the user denies the second time (or any subsequent time) and has this “Don’t ask again” checked then no further dialog boxes will appear when requesting that permission.

However, nothing in the Android SDK really tells us that they have checked this. If we request that permission again it will just come back as denied, just like any other time. So we need to handle it differently.

What we’re doing now is just storing a SharedPreference called ALREADY_REQUESTED_ACCESS_TO_CONTACTS that is false at the beginning and on the first request for permission, it gets set to true.

Thinking about this further, what we’re really after is whether or not we need to provide some extra instructions to the user or open up the Permissions/Privacy settings of the app so they can manually change the permissions themselves.

I think for a new release, we should get rid of alreadyRequestedAccessToContacts and replace it with something like permanentlyDeniedAccessToContacts.

This method would return true on iOS after the User has denied the permission request just once (because that’s all it takes on iOS) and will return true on Android only when the User has denied permission and checked off the “Don’t ask again” checkbox.

may-12-2018 10-19-28

paintedbicycle commented 6 years ago

Very interesting. I’ll test this tomorrow.

I’m down for whatever solution makes sense. Even a permissionsRequestState that can return the 4 states would be good. Just need to be able to recreate all 3 scenarios in my app, including never asked.

Paul

On May 12, 2018, at 6:20 PM, Joshua Pinter notifications@github.com wrote:

Fixed in 84b6ce3!

This is an interesting one, because Android handles things a little differently than iOS.

With Android, you can request for the same permission again if the User deny’s the first time. The second request will show the same dialog box but will also have a checkbox that says “Don’t ask again.”

If the user denies the second time (or any subsequent time) and has this “Don’t ask again” checked then no further dialog boxes will appear when requesting that permission.

However, nothing in the Android SDK really tells us that they have checked this. If we request that permission again it will just come back as denied, just like any other time. So we need to handle it differently.

What we’re doing now is just storing a SharedPreference called ALREADY_REQUESTED_ACCESS_TO_CONTACTS that is false at the beginning and on the first request for permission, it gets set to true.

Thinking about this further, what we’re really after is whether or not we need to provide some extra instructions to the user or open up the Permissions/Privacy settings of the app so they can manually change the permissions themselves.

I think for a new release, we should get rid of alreadyRequestedAccessToContacts and replace it with something like permanentlyDeniedAccessToContacts.

This method would return true on iOS after the User has denied the permission request just once (because that’s all it takes on iOS) and will return true on Android only when the User has denied permission and checked off the “Don’t ask again” checkbox.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

paintedbicycle commented 6 years ago

Is there only a promise version? Non promise version doesn’t appear public and there is no promise iOS version yet so it’s a mismatch.

Paul

On May 12, 2018, at 6:27 PM, Paul Wright paul@paintedbicycle.com wrote:

Very interesting. I’ll test this tomorrow.

I’m down for whatever solution makes sense. Even a permissionsRequestState that can return the 4 states would be good. Just need to be able to recreate all 3 scenarios in my app, including never asked.

Paul

On May 12, 2018, at 6:20 PM, Joshua Pinter notifications@github.com wrote:

Fixed in 84b6ce3!

This is an interesting one, because Android handles things a little differently than iOS.

With Android, you can request for the same permission again if the User deny’s the first time. The second request will show the same dialog box but will also have a checkbox that says “Don’t ask again.”

If the user denies the second time (or any subsequent time) and has this “Don’t ask again” checked then no further dialog boxes will appear when requesting that permission.

However, nothing in the Android SDK really tells us that they have checked this. If we request that permission again it will just come back as denied, just like any other time. So we need to handle it differently.

What we’re doing now is just storing a SharedPreference called ALREADY_REQUESTED_ACCESS_TO_CONTACTS that is false at the beginning and on the first request for permission, it gets set to true.

Thinking about this further, what we’re really after is whether or not we need to provide some extra instructions to the user or open up the Permissions/Privacy settings of the app so they can manually change the permissions themselves.

I think for a new release, we should get rid of alreadyRequestedAccessToContacts and replace it with something like permanentlyDeniedAccessToContacts.

This method would return true on iOS after the User has denied the permission request just once (because that’s all it takes on iOS) and will return true on Android only when the User has denied permission and checked off the “Don’t ask again” checkbox.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

joshuapinter commented 6 years ago

Non-Promise version of alreadyRequestedAccessToContacts added!

paintedbicycle commented 6 years ago

Just tested. Works well! Confirmed fixed.