surinfv
3/21/2018 - 12:22 PM

permissions Rx1

permissions with Rx 1


import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.text.TextUtils;

import com.ntrlab.velocityvue.R;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;

public class PermissionRetriever {
    private final static String LOG_TAG = LogUtils.makeLogTag(PermissionRetriever.class);
    private final static int REQUEST_PERMISSIONS_CODE = 999;
    private Runnable mPendingIfGrantedAction;
    private Runnable mPendingIfUnacceptedAction;
    private Fragment mFragment;
    private Activity mActivity;

    private final Map<String, String> mPermissionsRationalesMap = new HashMap<>();

    @Inject
    public PermissionRetriever() {
    }

    public static boolean hasPermission(Activity activity, String permission) {
        return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED;
    }

    public static boolean hasPermissions(Activity activity, String... permissions) {
        boolean granted = true;
        for (String permission : permissions) {
            granted &= hasPermission(activity, permission);
        }
        return granted;
    }

    public static boolean hasPermission(Fragment fragment, String permission) {
        return hasPermission(fragment.getActivity(), permission);
    }

    public static boolean hasPermissions(Fragment fragment, String... permissions) {
        return hasPermissions(fragment.getActivity(), permissions);
    }

    public PermissionRetriever withPermission(String permission) {
        mPermissionsRationalesMap.put(permission, "");
        return this;
    }

    public PermissionRetriever withPermission(String permission, String explanation) {
        mPermissionsRationalesMap.put(permission, explanation);
        return this;
    }

    public void runIfGranted(Activity activity, Runnable runnable) {
        runIfGrantedAndIfUnaccepted(activity, runnable, null);
    }

    public void runIfGranted(Fragment fragment, Runnable runnable) {
        runIfGrantedAndIfUnaccepted(fragment, runnable, null);
    }

    public void grant(Activity activity) {
        runIfGrantedAndIfUnaccepted(activity, null, null);
    }

    public void grant(Fragment fragment) {
        runIfGrantedAndIfUnaccepted(fragment, null, null);
    }

    public void runIfGrantedAndIfUnaccepted(Activity activity, Runnable ifGranted, Runnable ifUnaccepted) {
        mActivity = activity;
        mPendingIfGrantedAction = ifGranted;
        mPendingIfUnacceptedAction = ifUnaccepted;
        checkAndRun();
    }

    public void runIfGrantedAndIfUnaccepted(Fragment fragment, Runnable ifGranted, Runnable ifUnaccepted) {
        mFragment = fragment;
        mPendingIfGrantedAction = ifGranted;
        mPendingIfUnacceptedAction = ifUnaccepted;
        checkAndRun();
    }

    public void onPermissionResult(int requestCode) {
        if (getContext() != null && requestCode == REQUEST_PERMISSIONS_CODE) {
            if (isAllGranted()) {
                runGranted();
            } else {
                if (shouldShowRationale()) {
                    showRationaleToRequest();
                } else {
                    showRationaleToSettings();
                }
            }
        }
    }

    private void checkAndRun() {
        if (getContext() != null) {
            if (isAllGranted()) {
                runGranted();
            } else {
                request();
            }
        } else {
            LogUtils.e(LOG_TAG, "Context is null. I'm gonna do nothing!!!");
        }
    }

    private boolean isAllGranted() {
        boolean allGranted = true;
        if (!mPermissionsRationalesMap.isEmpty()) {
            List<Map.Entry<String, String>> granted = new ArrayList<>();
            for (Map.Entry<String, String> entry : mPermissionsRationalesMap.entrySet()) {
                if (permissionGranted(entry.getKey())) {
                    granted.add(entry);
                } else {
                    allGranted = false;
                }
            }
            mPermissionsRationalesMap.entrySet().removeAll(granted);
        }
        return allGranted;
    }

    private boolean permissionGranted(String permission) {
        return ActivityCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED;
    }

    private void runGranted() {
        if (mPendingIfGrantedAction != null) {
            mPendingIfGrantedAction.run();
        }
    }

    private void runUnaccepted() {
        mPermissionsRationalesMap.clear();
        if (mPendingIfUnacceptedAction != null) {
            mPendingIfUnacceptedAction.run();
        }
    }

    private void request() {
        Set<String> permissionsSet = mPermissionsRationalesMap.keySet();
        requestPermissions(permissionsSet.toArray(new String[permissionsSet.size()]));
    }

    private void requestPermissions(@NonNull String[] permissions) {
        if (mFragment != null) {
            mFragment.requestPermissions(permissions, REQUEST_PERMISSIONS_CODE);
        } else {
            ActivityCompat.requestPermissions(mActivity, permissions, REQUEST_PERMISSIONS_CODE);
        }
    }

    private boolean shouldShowRationale() {
        boolean should = true;
        for (String permission : mPermissionsRationalesMap.keySet()) {
            should &= shouldShowRequestPermissionRationale(permission);
        }
        return should;
    }

    private boolean shouldShowRequestPermissionRationale(@NonNull String permission) {
        if (mFragment != null) {
            return mFragment.shouldShowRequestPermissionRationale(permission);
        } else {
            return ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permission);
        }
    }

    private void showRationaleToRequest() {
        prepareDialog()
                .setPositiveButton("Ask again", (d, i) -> request())
                .show();
    }

    private void showRationaleToSettings() {
        prepareDialog()
                .setPositiveButton("Settings", (d, i) -> getContext().startActivity(intentToSettings()))
                .show();
    }

    private AlertDialog.Builder prepareDialog() {
        StringBuilder message = new StringBuilder("For using some app features we need to you grant this permissions list:\n");
        for (Map.Entry<String, String> entry : mPermissionsRationalesMap.entrySet()) {
            message.append("\n").append(cutPermissionName(entry.getKey()));
            if (!TextUtils.isEmpty(entry.getValue())) {
                message.append(" - ").append(entry.getValue());
            }
        }
        return new AlertDialog.Builder(getContext())
                .setTitle("You have denied permissions")
                .setMessage(message)
                .setOnCancelListener((d) -> runUnaccepted())
                .setNegativeButton(R.string.cancel, (d, w) -> runUnaccepted());
    }

    private String cutPermissionName(String permission) {
        int lastDotIndex = permission.lastIndexOf('.') + 1;
        return permission.substring(lastDotIndex).replaceAll("_", " ");
    }

    private Intent intentToSettings() {
        return new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                .setData(Uri.fromParts("package", getContext().getPackageName(), null));
    }

    private Context getContext() {
        if (mFragment != null) {
            return mFragment.getActivity();
        } else {
            return mActivity;
        }
    }
}