karumi / dexter Goto Github PK
View Code? Open in Web Editor NEWAndroid library that simplifies the process of requesting permissions at runtime.
Home Page: http://karumi.com
License: Apache License 2.0
Android library that simplifies the process of requesting permissions at runtime.
Home Page: http://karumi.com
License: Apache License 2.0
I can't find SnackbarOnDeniedPermissionListener.Builder.withCallback
API
com.karumi:dexter:2.2.2
Hi guys,
I just found out a behaviour that I was not expecting, although I'm not quite sure it should be consider as an issue. But definitely it's something I wasn't expecting.
If a permission is requested from a background thread the result is returned on the main thread.
I was having a look at the code and the reason seems to be that when the internal activity that the lib uses is started it changes the thread under the covers.
I'd like to know what are you thoughts about this.
Cheers.
The Snackbar shown after a permission is denied could show an action to enable the permission in app settings
If one handles onPermissionRationaleShouldBeShown
to show a rationale to the user explaining why we need that particular permission - for instance, with an AlertDialog
- and call token.continuePermissionRequest()
to show the request permission dialog again, this leads into two dialogs.
Is there anyway to avoid this? I mean, show a rationale within the request permission dialog?
I have got crash error when I trying to request permission. Which below:
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=42, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.feelsfashionltd.feels.debug/com.karumi.dexter.DexterActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.view.ViewGroup.getContext()' on a null object reference at android.app.ActivityThread.deliverResults(ActivityThread.java:3988) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3301) at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3359)ย at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2549)ย at android.app.ActivityThread.access$900(ActivityThread.java:150)ย at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1394)ย at android.os.Handler.dispatchMessage(Handler.java:102)ย at android.os.Looper.loop(Looper.java:168)ย at android.app.ActivityThread.main(ActivityThread.java:5845)ย at java.lang.reflect.Method.invoke(Native Method)ย at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)ย at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)ย Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.view.ViewGroup.getContext()' on a null object reference at android.support.design.widget.Snackbar.<init>(Snackbar.java:180) at android.support.design.widget.Snackbar.make(Snackbar.java:209) at com.karumi.dexter.listener.multi.SnackbarOnAnyDeniedMultiplePermissionsListener.showSnackbar(SnackbarOnAnyDeniedMultiplePermissionsListener.java:63) at com.karumi.dexter.listener.multi.SnackbarOnAnyDeniedMultiplePermissionsListener.onPermissionsChecked(SnackbarOnAnyDeniedMultiplePermissionsListener.java:58) at com.karumi.dexter.listener.multi.CompositeMultiplePermissionsListener.onPermissionsChecked(CompositeMultiplePermissionsListener.java:54) at com.karumi.dexter.MultiplePermissionListenerThreadDecorator$1.run(MultiplePermissionListenerThreadDecorator.java:45) at com.karumi.dexter.MainThread.execute(MainThread.java:32) at com.karumi.dexter.MultiplePermissionListenerThreadDecorator.onPermissionsChecked(MultiplePermissionListenerThreadDecorator.java:43) at com.karumi.dexter.DexterInstance.onPermissionsChecked(DexterInstance.java:264) at com.karumi.dexter.DexterInstance.updatePermissionsAsDenied(DexterInstance.java:247) at com.karumi.dexter.DexterInstance.onPermissionRequestDenied(DexterInstance.java:148) at com.karumi.dexter.Dexter.onPermissionsRequested(Dexter.java:176) at com.karumi.dexter.DexterActivity.onRequestPermissionsResult(DexterActivity.java:54) at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6564) at android.app.Activity.dispatchActivityResult(Activity.java:6443) at android.app.ActivityThread.deliverResults(ActivityThread.java:3984) at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3301)ย at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3359)ย at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2549)ย at android.app.ActivityThread.access$900(ActivityThread.java:150)ย at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1394)ย at android.os.Handler.dispatchMessage(Handler.java:102)ย at android.os.Looper.loop(Looper.java:168)ย at android.app.ActivityThread.main(ActivityThread.java:5845)ย at java.lang.reflect.Method.invoke(Native Method)ย at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)ย at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)ย
Can you check this error and improve it?
First I request Storage permission -> choose allow
Then I request Camera, Record Audio and Storage permission -> Deny all -> Crash
2.2.2
Is there any proguard rule for Dexter?
Hi, I'm using Dexter-Lib on a project and I am having a problem that always displays a black screen. The details to simulate are simple:
1 - build.app configurations.
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
defaultConfig {
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
multiDexEnabled true
}
}
2 - My style.
<style name="LaunchTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorAccent">@color/material_white_1000</item>
<item name="colorControlNormal">@color/material_white_1000</item>
<item name="colorControlActivated">@color/material_white_1000</item>
<item name="colorControlHighlight">@color/material_white_1000</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
3 - I create a simple builder to call the Dexter Library.
PermissionValidator.with(activity)
.setTitle(R.string.permission_read_contacts_title)
.setMessage(R.string.permission_read_contacts_message)
.setDeniedMessage(R.string.permission_read_contacts_denied_message)
.setPermission(Manifest.permission.READ_CONTACTS)
.setOnPermissionGrantedListener(new OnPermissionGrantedListener() {
@Override
public void onPermissionGranted() {
activity.startActivityForResult(getContactsIntent(), PICK_CONTACT_REQUEST_CODE);
}
})
// .setOnPermissionRationaleShouldBeShownListener(new DefaultOnPermissionRationaleShouldBeShownListener())
.validate();
4 - The code called by Validate (if necessary).
if (!Dexter.isRequestOngoing()) {
Dexter.checkPermission(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse response) {
if (onPermissionGrantedListener != null) {
onPermissionGrantedListener.onPermissionGranted();
}
}
@Override
public void onPermissionDenied(PermissionDeniedResponse response) {
if (onPermissionDeniedListener != null) {
onPermissionDeniedListener.onPermissionDenied();
}
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permission, final PermissionToken token) {
if (onPermissionRationaleShouldBeShownListener != null) {
onPermissionRationaleShouldBeShownListener.onPermissionRationaleShouldBeShown(context, token, title, message, deniedMessage);
}
}
}, permission);
}
This code works perfectly when you define a Toolbar. But when I do this in my LoginActivity (which does not use a Toolbar), I get one of two messages when I call the .validate () method and a beautiful black screen:
1 - You need to use a Theme.AppCompat theme (or descendant) with this activity`.
2 - android.view.WindowLeaked: Activity br.com.mobicare.recarga.ui.activity.LaunchActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{707ca14 V.E...... R....... 0,0-1080,737} that was originally added here`
Could anyone help me?
I see your using static references to instance, this means if your activity is killed during the request (can happen with rotate or if the user switches out of the app to google a permission) this will not work.
onPermissionRationaleShouldBeShown(List permissions, PermissionToken token) fires always when Dexter.checkPermissions is called
Cannot understand why this happens but when I firstly call Dexter.checkPermissions with two permissions: Manifest.permission.ACCESS_FINE_LOCATION and Manifest.permission.ACCESS_COARSE_LOCATION onPermissionRationaleShouldBeShown is not called but instead dialog with permission request shows. What is more there is no "Never ask again" checkbox:
When I deny and call method second time, onPermissionRationaleShouldBeShown is called and I show my alertDialog and then permission request dialog has "Never ask again" checkbox.
Dexter.checkPermissions(new CustomPermissionListener(), Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);
Nexus 5, 6.0.1
com.karumi:dexter:2.2.2
Review the behaviour when Dexter is called from an activity onCreate
and from the application. See if there is something we can do if it fails
This error is happenning on sample application in genymotion vm (preview of google nexus 5x, android 6) :
Dexter.checkPermission(Manifest.permission.INTERNET, new EmptyPermissionListener() {
immediatelly FC the package manager, the logcat :
11-25 12:11:01.575 3708-3708/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.packageinstaller, PID: 3708
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity}: java.lang.NullPointerException: Attempt to get length of null array
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to get length of null array
at com.android.packageinstaller.permission.ui.GrantPermissionsActivity.computePermissionGrantState(GrantPermissionsActivity.java:277)
at com.android.packageinstaller.permission.ui.GrantPermissionsActivity.updateDefaultResults(GrantPermissionsActivity.java:327)
at com.android.packageinstaller.permission.ui.GrantPermissionsActivity.onCreate(GrantPermissionsActivity.java:100)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)ย
at android.app.ActivityThread.-wrap11(ActivityThread.java)ย
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)ย
at android.os.Handler.dispatchMessage(Handler.java:102)ย
at android.os.Looper.loop(Looper.java:148)ย
at android.app.ActivityThread.main(ActivityThread.java:5417)ย
at java.lang.reflect.Method.invoke(Native Method)ย
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)ย
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)ย
11-25 12:11:01.576 848-946/system_process W/ActivityManager: Force finishing activity com.android.packageinstaller/.permission.ui.GrantPermissionsActivity
Add a way to show the Dialog after a defined delay
The permission delay appears just when we call it. If we want to show it after some time, we've to write it in our apps
Call Dexter.checkPermission()
2.2.2
If you want, I can do it and launch a PR. Are you interested on it? If you are not interested in this feature, don't hesitate to simply close this issue :ยท)
Thanks for your work!
Android 6.0 version of the device can run normally, but run on earlier versions of the equipment, procedure will collapse.
if (Build.VERSION.SDK_INT >= 23) {
// Marshmallow+
} else {
// Pre-Marshmallow
}
But this will cause the program to become bloated.A better solution is to use the Support Library v4 repository method to replace the original method, it will save for different versions of the device respectively provide code:
// Modify Activity.checkSelfPermission()
ContextCompat.checkSelfPermission()
The code is more concise
The transparent activity is no longer started with FLAG_ACTIVITY_NEW_TASK, which results in the following crash:
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:672)
at android.app.ContextImpl.startActivity(ContextImpl.java:659)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:331)
at com.karumi.dexter.DexterInstance.startTransparentActivityIfNeeded(DexterInstance.java:216)
at com.karumi.dexter.DexterInstance.checkMultiplePermissions(DexterInstance.java:322)
at com.karumi.dexter.DexterInstance.checkSinglePermission(DexterInstance.java:294)
at com.karumi.dexter.DexterInstance.checkPermission(DexterInstance.java:80)
at com.karumi.dexter.Dexter.checkPermission(Dexter.java:90)
I know 3.0.0 isn't released yet; just wanted to bring it to your attention in case it wasn't known.
If all requested permissions are already granted when invoking one of the Dexter.checkPermission(s)(OnSameThread)
, startTransparentActivityIfNeeded()
should not start DexterActivity
. Thus preventing any kind of flicker and animation when opening/closing activities.
When checking for permissions already granted, I get a slight flicker and slide animation with a translucent activity with a few shadows.
I have no clue... I have two classes, implemented with the same exact pattern, one of them shows the flicker, the other doesn't. They check for different permissions but I tried to replicate everything in the working class into the non-working class but I can't get it to work.
For some strange reason, I have a piece of code fully working (no flicker, no animation) and another piece of code not working (shows flicker, shows animation). I can't really understand the differences between them to describe the steps to reproduce.
That's why I'm suggesting to not even start DexterActivity
if all required permissions are already granted. I know this is supposed to be a translucent activity, but why are we opening it if we are going to close it right away since there are no dialogs to show?
v2.3.0
This is probably not a lib issue, but the one of not understanding one and I'm sure some other devs have the same question.
I ask for permission with PermissionListener and override those three methods. What happens in permission denied is up to me. But when I (for example, want to fetch location of the user) and he/she didn't gave the app permission to access FINE_LOCATION, it's up to me to save that permission denied somewhere (SharedPreferences?) and then in that code for fetching, I have to check everytime the state of that permission that I previously saved in (SharedPreferences?)?
My question is then, has the library some in-built mechanism to save if the permission is denied and then with that I can check that some code shouldn't be executed? For the case when permission is given to the app, everything is working fine out of the box.
btw. great lib, helps a lot :) ๐
I am creating a new permission request after showing the rationale to the user, and the library si failing with the exception:
Only one Dexter request at a time is allowed
How to handle SYSTEM_ALERT_WINDOW permission using Dexter.
Probably because of the transparent activity.
A possible fix is:
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
2.3.0
How can I deal this๏ผ
java.lang.IllegalStateException: Only one permission request at a time. Currently handling permission: [android.permission.WRITE_EXTERNAL_STORAGE]
11-20 00:15:17.036 27963-27963/? E/CustomActivityOnCrash: at com.karumi.dexter.DexterInstance.checkPermission(DexterInstance.java:51)
11-20 00:15:17.036 27963-27963/? E/CustomActivityOnCrash: at com.karumi.dexter.Dexter.checkPermission(Dexter.java:52)
When you request a permission, Dexter makes note that a permission request is outstanding. If I previously denied a permission, I'll get the callback showPermissionRationale(PermissionToken)
. We're supposed to use this to continue our permission request with PermissionToken.continuePermissionRequest()
or cancel it with PermissionToken.cancelPermissionRequest()
. However, if I choose to show an AlertDialog
(as is done in the SampleActivity
, the user could rotate the device, leading to me losing access to my token and being unable to cancel or continue the request.
This would lead to the crasher described in #14, which was fixed by locking the orientation of the sample app.
What I'd like to see is an example on how you suggest we recover our state after a device rotation. Specifically, what is your suggested way to persist the PermissionToken
?
It'd be great if this were in the sample app.
Application should ask camera permission at first time camera call from my app.
After installing application in device when i click camera button it is not showing camera permission dialog instead it is directly opening camera. but after clearing app data in application setting. it started showing permission request dialog. Now started work fine. even i am targating api 23 and my device also using marshmallow. if change the package name of app then it work normal as i want
I am using latest version
When you request for a Manifest.permission.ACCESS_COARSE_LOCATION
or Manifest.permission.ACCESS_FINE_LOCATION
Dexter doesn't work. It is because the hashcode of these permissions is a negative value and you can't use a nevative value as a requestCode
.
I have this use case where I'm using SnackbarOnDeniedPermissionListener
to show a Snackbar notify the user of some denied permission with the Settings button allowing them to enable the required permission.
But I feel the need to perform some action when the Snackbar is dismissed (manually by opening the settings button or automatically when it times out). But I don't have access to the Snackbar instance so I can't invoke setCallback
to handle the onDismissed
callback. As such, I can't use SnackbarOnDeniedPermissionListener
and had to roll out my own implementation of the same thing.
Maybe implement a withCallback
method on the SnackbarOnDeniedPermissionListener
?
What do you guys think? I could open a pull request for this...
I detect memory leaks by the library(https://github.com/square/leakcanary) in my app.It report this https://drive.google.com/open?id=0BzO_M3MAsb-CbFVkQU4tclRrMDg
1-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: FATAL EXCEPTION: main
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: Process: com.karumi.dexter.sample, PID: 20300
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: java.lang.IllegalStateException: Only one permission request at a time. Currently handling permission: [android.permission.READ_CONTACTS]
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.karumi.dexter.DexterInstance.checkPermission(DexterInstance.java:51)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.karumi.dexter.Dexter.checkPermission(Dexter.java:53)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.karumi.dexter.sample.SampleActivity.onContactsPermissionButtonClicked(SampleActivity.java:70)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.karumi.dexter.sample.SampleActivity$$ViewBinder$2.doClick(SampleActivity$$ViewBinder.java:34)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.view.View.performClick(View.java:5198)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:21147)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-23 17:17:32.121 20300-20300/com.karumi.dexter.sample E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
When the user cancels a permission Dexter lets you show a rationale to your user, if the token is not used ever, the permission request might get stuck
What for two callbacks?
@Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
@Override public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
May be the one with boolean will be less code?
@Override public void onPermissionResult(PermissionGrantedResponse response) {
if(response.isGranted()){...} else {...}
}
?
When asking for permissions, the invisible activity is always created, this might cause some issues if Dexter is called from the onCreate
or onResume
methods of your own activity (as it will force another call to onCreate
& onResume
once the inner activity is dismissed). We should only create the inner Activity
iff ActivityCompat.requestPermissions
is going to be called.
For calling checkSelfPermission
we should use the provided application context.
I am using Dexter.checkPermissions to ask for Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE.
After user grant access or deny access, it should execute nothing.
It closes the FragmentActivity.
PermissionUtil
public static void checkMicrophoneWriteStoragePermissionVoiceMessage(final Context context, final PermissionListener listener) {
Dexter.checkPermissionsOnSameThread(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.isAnyPermissionPermanentlyDenied()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.app_name)
.setMessage(R.string.permission_microphone_voice_message_never_ask_again)
.setNeutralButton(R.string.ok, null)
.create()
.show();
listener.onPermissionDenied();
return;
}
if (report.areAllPermissionsGranted()) {
listener.onPermissionGranted();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.app_name)
.setMessage(R.string.permission_microphone_voice_message_denied)
.setNeutralButton(R.string.ok, null)
.create()
.show();
listener.onPermissionDenied();
}
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, final PermissionToken token) {
new AlertDialog.Builder(context)
.setMessage(R.string.permission_microphone_voice_message_rationale)
.setPositiveButton(R.string.button_allow, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
token.continuePermissionRequest();
}
})
.setNegativeButton(R.string.button_deny, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
token.cancelPermissionRequest();
}
})
.show();
}
}, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
public interface PermissionListener {
void onPermissionGranted();
void onPermissionDenied();
}
In Fragment:
private void getVoiceMessagingPermission() {
PermissionUtil.checkMicrophoneWriteStoragePermissionVoiceMessage(mContext, toggleUiForVoiceMessagingPermissionListener);
}
private PermissionUtil.PermissionListener toggleUiForVoiceMessagingPermissionListener = new PermissionUtil.PermissionListener() {
@Override
public void onPermissionGranted() {
// do nothing
Toast.makeText(mContext, "Voice Messaging Permission Granted.", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied() {
// do nothing
Toast.makeText(mContext, "Voice Messaging Permission Denied.", Toast.LENGTH_SHORT).show();
}
};
compile 'com.karumi:dexter:2.2.2'
Sorry please delete the issue
With the current Dexter implementation we are only allowed to request one permission at a time. We have to add a new feature to the library to be able to request multiple permissions with just one call to the library.
Snapshot:
Proguard mapping info:
com.karumi.dexter.Dexter -> com.karumi.dexter.Dexter:
com.karumi.dexter.DexterInstance instance -> a
com.karumi.dexter.DexterInstance -> im:
android.app.Activity activity -> i
PR #25 have tried to fix this issue. Please review and test it.
Thanks a lot!
android support library 23.1.1 has been defind "borderWidth"
There seems to be a problem with the current usage of the library, people is often surprised with the Only one Dexter request at a time is allowed
exception and are forced to write a snippet similar to:
if (!Dexter.isRequestOngoing()) {
Dexter.checkPermission(someListener, Manifest.permission.RECORD_AUDIO);
}
We can simplify the library usage by removing the exception and notifying an optional callback if there is a problem instead of forcing everyone to handle that scenario. Adding a new parameter to every Dexter method to pass the optional callback seems to be a non-scalable option but the only one compatible with the current implementation.
Thoughts are welcome!
As the library is getting bigger we need acceptance tests to verify all the cases we are handling.
Playing around with permissions in UI tests is usually a bad idea but this project is probably the best to do it anyways.
Do some research to run one test at a time (probably with Spoon) and reset device permissions before the execution of each test. It will be slow as hell but probably better than nothing.
There is a blog post about permissions:
https://commonsware.com/blog/2015/11/09/you-cannot-hold-nonexistent-permissions.html
That explains that the compatibility library does not handle well the permissions in Android versions before a certain permission was added. I was planning to create a little snippet to deal with this issue, but having this library it would be convenient if it would take care of it.
I opened an issue talking about adding a new parameter to notify Dexter errors (#53) and seems to me that adding new parameters to the current API will eventually make it impossible to develop.
I think it would be much better to create a fluent API to use Dexter both in readability and extensibility. The proposed API would be used like:
public void someMethod() {
Dexter.withPermissions(Manifest.permission.CAMERA, Manifest.permission.READ_CONTACTS)
.withListener(someListener)
.withErrorListener(errorListener)
.onSameThread()
.check();
}
Thoughts are more than welcome.
Show a default Dialog
when requesting a permission after the first "Deny"
Nothing appears
2.2.2
It only happens when I use the default dialogPermissionListener
:
DialogOnDeniedPermissionListener.Builder
.withContext(context)
.withTitle("Camera permission")
.withMessage("Camera permission is needed to take pictures of your cat")
.withButtonText(android.R.string.ok)
.withIcon(R.mipmap.my_icon)
.build();
Using this sample code:
PermissionListener snackbarPermissionListener =
SnackbarOnDeniedPermissionListener.Builder
.with(rootView, "Camera access is needed to take pictures of your dog")
.withOpenSettingsButton("Settings")
.build();
Dexter.checkPermission(
new CompositePermissionListener(snackbarPermissionListener, dialogPermissionListener),
Manifest.permission.CAMERA
);
Is Dexter safe to use in a multi process environment ?
We should investigate if it's possible to add a new method in PermissionListener
to notify clients when the user denies a permission and asks Android to never ask him again about it.
Hi there,
the library looks promising, thanks. However it's very easy to crash your sample app, all it takes is tapping on a couple of buttons rapidly (before the dialog box pops up):
FATAL EXCEPTION: main
Process: com.karumi.dexter.sample, PID: 2514
java.lang.IllegalStateException: Only one Dexter request at a time is allowed
at com.karumi.dexter.DexterInstance.checkNoDexterRequestOngoing(DexterInstance.java:215)
at com.karumi.dexter.DexterInstance.checkPermissions(DexterInstance.java:80)
at com.karumi.dexter.DexterInstance.checkPermission(DexterInstance.java:69)
at com.karumi.dexter.Dexter.checkPermission(Dexter.java:57)
at com.karumi.dexter.sample.SampleActivity.onContactsPermissionButtonClicked(SampleActivity.java:74)
at com.karumi.dexter.sample.SampleActivity$$ViewBinder$3.doClick(SampleActivity$$ViewBinder.java:43)
at butterknife.internal.DebouncingOnClickListener.onClick(DebouncingOnClickListener.java:22)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
How could it be prevented? isRequestingPermission
is private and invisible from outside, so the only way would be to create an own wrapper around Dexter and track all permission requests ourselves, but this feels cumbersome. Any ideas?
when I call checkPermission,it will call onResume
Dexter.checkPermissions
2.3.0
Calling Dexter.checkPermissionOnSameThread
shouldn't crash if a looper has already been prepared
03-14 17:00:16.549 16003-16614/com.blah E/AndroidRuntime: FATAL EXCEPTION: IntentService[GeofenceTransitionsIntentService]
Process: com.blah, PID: 16003
java.lang.RuntimeException: Only one Looper may be created per thread
at android.os.Looper.prepare(Looper.java:82)
at android.os.Looper.prepare(Looper.java:77)
at com.karumi.dexter.WorkerThread.<init>(WorkerThread.java:30)
at com.karumi.dexter.ThreadFactory.makeSameThread(ThreadFactory.java:40)
at com.karumi.dexter.Dexter.checkPermissionOnSameThread(Dexter.java:60)
at ...
In a background thread, call Looper.prepare()
before calling Dexter.checkPermissionOnSameThread
2.2.1
According to stack overflow adding the following to WorkerThread.java
should fix it (or at least this exception):
if (Looper.myLooper() == null) {
Looper.prepare();
}
I haven't tested the fix but it should work. I'll see about doing a pull request soon but someone feel free to beat me to it.
The class Dexter.java avaliable by gradle doesn't contain the method isRequestOngoing and the class Dexter.java avaliable in the github repository does. Can you guys publish another version of Dexter to use by gradle that contains isRequestOngoing method?
I released my app using dexter and I found that there is some bugs with Android system and I cause Only one dexter request is allowed at a time
exception.
I'm hoping not to check permission stuff under API version 23.
Here is my codes and error message.
Dexter.checkPermissions(new MultiplePermissionsListener() {
@Override
public void onPermissionsChecked(MultiplePermissionsReport report) {
if (report.areAllPermissionsGranted())
showCropSheetView();
else
Snackbars.alert(CropActivity.this, getString(R.string.errorMessageExternalStoragePermission));
}
@Override
public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
Snackbars.alert(CropActivity.this, getString(R.string.errorMessageExternalStoragePermission));
token.continuePermissionRequest();
}
}, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);
Hi guys!
Would it be possible for you to follow git-flow for the repo?
It can be a bit confusing, if you've got not-yet-released features on your master
branch.
E.g. I wanted to peek into your sample
module, and saw completely different PermissionListener
being used. And I needed to perform a small investigation to see if I was doing something wrong or if it was just something not yet released.
Thanks
Greetings Dexter team,
This issue could be related to issue #45
I have an Activity (Webview) which I call from browser with View intent and request for permissions through dexter and when I do this opens up the main activity since the DexterActivity class is called as NEW TASK. This would be against my application flow and I'm sure that this would affect many.
I'm requesting MultiplePermissions.
Dexter is an extremely useful framework and I have integrated it successfully through out my app but due to this issue I have to rework the flow.
I have 2 activities in my project
Activity#1 is a kind of a StartupActivity, which handles Registration/Login and a "Splashscreen" in which some REST Calls have to be made.
If everything is fine within the SplashScreen the MainActivity will be started and Activity#1 will be finished.
Even if the MainActivity (singleTop) is resumed, the StartupActivity is shown upfront.
In the MainActivity I call Dexter.checkPermission() after onCreate etc. before I check for permissions I call isRequestOngoing() which returns false...
2.2.2
Dexter to ask again for permissions if they are turned off in the app settings after having accepted them
When accepting permissions and afterwards turning them off in the settings; I'm expecting Dexter to be called in the onResume method in my BaseActivity. Since there is already a running instance it is called only once.
Accept permissions, go to settings, go back to the app and see that the permissions are not requested in the onResume
@Override
protected void onResume() {
super.onResume();
if (!Dexter.isRequestOngoing()) {
Dexter.checkPermissions(new MultiplePermissionsListener() {
@Override public void onPermissionsChecked(MultiplePermissionsReport report) {/* ... */}
@Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {/* ... */}
}, android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.CAMERA);
}
}
com.karumi:dexter:2.2.2
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.