Karumi / Dexter

Android library that simplifies the process of requesting permissions at runtime.
http://karumi.com
Apache License 2.0
5.23k stars 670 forks source link

When permissions dialog is presented, and the app is backgrounded, the listener(s) remain active, even if set to null in the activity. #126

Open elliott-accolade opened 7 years ago

elliott-accolade commented 7 years ago

Expected behaviour

If I background the app while the permissions dialog for any reason (phone call, text message, etc.), I want to be able to resume where I was when I return to the app, within reason.

Actual behaviour

(Behavior differs between APIs. Below is a description of what happens on API 24) Background the app (not killing it). When restarted, the first thing the user sees is the permission dialog; The activity isn't even on the screen yet. Pressing Deny, then going back into the app and pressing the button that triggers the permissions requirement, we can see by debugging that the original listener is still active, even though we set it to null onStop. When the button is clicked again, nothing happens because there is an existing instance:

03-07 15:34:31.036 4709-4709/com.xxxxxxxxx.mobile.dev D/CardDetailsActivity: Trigger onFrontImageClicked()
03-07 15:34:31.038 4709-4709/com.xxxxxxxxx.mobile.dev E/CardDetailsActivity: Dexter: There was an error: REQUEST_ONGOING
03-07 15:34:44.796 4709-4709/com.xxxxxxxxx.mobile.dev D/CardDetailsActivity: Trigger onFrontImageClicked()
03-07 15:34:44.798 4709-4709/com.xxxxxxxxx.mobile.dev E/CardDetailsActivity: Dexter: There was an error: REQUEST_ONGOING

Backgrounding and killing the app seems to work as expected: I kill the app from the list of apps, open the app again, click the button, and a new dialog appears.

Steps to reproduce

  1. Start your listeners onCreate.
  2. Null your listeners onStop
  3. Click the button that triggers the permissions dialog
  4. Background (do not kill) the app.
  5. Re-open the app --> Observe: the permissions dialog comes back up. Pressing Deny stops app from opening. Attempting to open again, then clicking the button w/ permissions leads to crash.

Version of the library

4.0.0

Hopefully a future release will allow folks to dismiss the Permissions dialog programatically.

Serchinastico commented 7 years ago

Hi @elliott-accolade

First of all, thank you for your detailed report!

I'm thinking about the execution flow in your description and I'm seeing a small inconsistency that might (or not) be the source of the problem. You are creating your listeners in the onCreate method and nulling them in the onStop method, I do think they are not symmetrical, your activity might be never recreating those listeners, meaning you will be passing null listeners to Dexter (we have to assert those now that I think about it).

Can you check if that's the issue?

I'd also love to be able to dismiss the permissions dialog but it's a system activity and we have no control over it, we just ask Android to display it and we receive events with a "listener".

elliott-accolade commented 7 years ago

Hi @Serchinastico! Thanks for your quick reply. I apologize for not updating my question yesterday after some more testing; You're right - setting the listeners to null in the onStop lifecycle method would cause some issues when the user pressed the button to request the permissions again, so I removed the part where I null the listeners.

As of right now, I am initializing the listeners in onCreate, then using Dexter.withActivity(Activity).withPermissions( ... ) ... to start the permissions dialog. Nothing is being nulled out.

The real issue we're having, as you pointed out, is that we can't dismiss the permissions dialog when the app is put to background. I noticed that when the user requests permissions, if they haven't been granted, a transparent DexterActivity is started where I assume you're "hosting" the System's permission dialog. When I kill the app after requesting (but not accepting) the permissions, I noticed that the onDestroy is called on the DexterActivity, and when I reopen the app, I am able to request the permissions again, whereas if I just put the app to background and came back into it, pressing the button that requires permissions would fail silently with the ONGOING_REQUEST message in the logs, which the user can't see and is confusing.

This may be related: When I kill any app normally, I am brought back to the Manifest-specified Main activity; But I notice when I kill the app with Dexter after requesting permissions and not confirming them, it brings me back to the activity where the permissions were being requested, as if I'm launching the app based on the Context that Dexter is retaining.

TL;DR: These two issues are probably related to Dexter retaining the context when the app is pushed to background, or killed. We're looking for a way to dismiss the system dialog when the user does this; Even a way to access the 'Deny' button would be something. At this point, from what you're saying, there won't be a way to dismiss this dialog for the foreseeable future?

Thank you very much for your help - this library is super easy to use and helpful!

robl2e commented 7 years ago

Hi, I'm encountering this issue as well. Have you discovered a workaround or solution to do this issue. From reading the comments above I'm trying to understand, if the issue is related to Dexter itself or the system Activity that is presenting the alert? I like Dexter, but may need to look at alternative solutions because of this issue.

From debugging this scenario, I noticed the DexterInstance's isShowingNativeDialog is true, even though the alert is not present visually, so I'm wondering if there's a way to force cancel the current permission request as a workaround.

Thanks!

Alankar0416 commented 6 years ago

+1. Please let us know of any fix if available.

yev-kanivets commented 5 years ago

+1, in my case it can be reproduced by clicking on App Links.