Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle permission requests outside Activity and Fragment?

I'm developing a custom compound View that needs to access external storage. How can I implement the permission handling without involving outside parties, i.e. Activity or Fragment?

I get that I can request the permissions using the View's context, but how can I handle onRequestPermissionsResult() inside the View? Is it even possible?

If it's not possible, what would be the most elegant solution to handle something like this?

like image 550
Magnus Avatar asked Apr 07 '16 18:04

Magnus


People also ask

How do you ask permission runtime again if the user deny for the first time?

I don't think you should ask permission again if the user denies, all you can do is, don't take the app forward , just show them a toast or a dialog telling them that this permission is required for the app to work correctly and ask them to grant permission in the settings.


1 Answers

You can't work with permissions without the instance of the activity, but you can do your code prettier. If you want to send a request and handle it in one place, then you can use the example below.

Just create something looks like BaseActivity and put there such code

public class PermActivity extends Activity {

    interface OnPermissionCallback{
        void requestResult(String[] permissions, int[] grantResults);
    }

    private SparseArray<OnPermissionCallback> permissionCallback = new SparseArray<>();

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        permissionCallback.get(requestCode).requestResult(permissions, grantResults);
    }

    public void addPermissionCallback(int requestCode, OnPermissionCallback  callback){
        permissionCallback.put(requestCode, callback);
    }
}

And now in our client code, we can do something like that

class SomeClasThatWorksWithPerms{

    private PermActivity activity;

    public SomeClasWorksWithPerms(PermActivity activity) {
        this.activity = activity;
    }

    void foo(){
        if (ContextCompat.checkSelfPermission(activity, WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
            // do something
        }else {
            activity.addPermissionCallback(0, (perms, grantResults) -> {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    foo(); // try one more
                }
            });
            activity.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 0);
        }
    }
}

I have used spareArray and indexation by the request code but you can use another way of storing callbacks.

It's very simple example, you can see something more serious there https://github.com/mrizyver/Fl_Launcher/blob/master/app/src/main/java/com/izyver/fllauncher/presentation/activity/FlActivity.kt - as you can see, it is activity https://github.com/mrizyver/Fl_Launcher/blob/master/app/src/main/java/com/izyver/fllauncher/presentation/loaders/WallpaperLoader.kt - our client code that works with permissions

like image 89
Izyver Avatar answered Oct 21 '22 14:10

Izyver