In order to facilitate the use of permission application and avoid unnecessary duplicate code, WITH the help of materials provided by some open source projects, I made a further encapsulation of permission application, encapsulating permission-related operations into classes, and finally opening only one calling method for external convenience.

The specific operation steps are as follows:

1. Copy the following PermissionsUtil class code into your project

import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.provider.Settings; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.ActivityCompat; import android.support.v4.content.PermissionChecker; import android.support.v7.app.AlertDialog; import java.util.HashMap; import java.util.Map; /*** * @date create time 2018/8/18 21:21 * @author Public class PermissionsUtil extends Activity {private static final int PERMISSION_REQUEST_CODE = 64; private static final int REQUEST_SETTING_CODE = 121; private String[] permission; private String key; private boolean isShowTip; private PermissionTipInfo tipInfo; private static Map<String, OnPermissionCallback> listenersMap = new HashMap<>(); /*** * permission request * @param context Request permission context, It is best to pass the current Activity instance in an Activity or fragment * @param Permission Required permission * @param onPermissionCallback Callback interface after permission request */ public static void requestPermission(Context context, String[] permission, OnPermissionCallback onPermissionCallback) { requestPermission(context, null, permission,true, onPermissionCallback); } /*** * how to apply for permission * @param context It is best to pass the current Activity instance if it is in an Activity or fragment * @param Permission Permission to apply for * @param isShowTip Whether to display a dialog (when permission is denied) * @param Public static void requestPermission(Context Context, String[] permission, boolean isShowTip, OnPermissionCallback onPermissionCallback) { requestPermission(context, null, permission, isShowTip, onPermissionCallback); } /*** * how to apply for permission * @param context It is best to pass the current Activity instance if it is in an Activity or fragment. * @param tipInfo Indicates the type of dialog box displayed when permissions are denied or disabled. * @param Permission Indicates the permissions to be applied for * @param IsShowTip Whether to display the dialog box (when permission is denied) * @param onPermissionCallback Callback interface after permission request */ public static void requestPermission(Context) context, PermissionTipInfo tipInfo, String[] permission, boolean isShowTip, OnPermissionCallback onPermissionCallback) { Intent intent = new Intent(context, PermissionsUtil.class); intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);if(tipInfo ! = null) { intent.putExtra("tipInfo", tipInfo);
        }

        String key = System.currentTimeMillis() + "";
        intent.putExtra("key", key);
        intent.putExtra("permission", permission);
        intent.putExtra("isShowTip", isShowTip);
        listenersMap.put(key, onPermissionCallback);
        context.startActivity(intent);
        if (context instanceof Activity) {
            ((Activity) context).overridePendingTransition(0, 0);
        }
    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = getIntent();
        key = intent.getStringExtra("key");
        tipInfo = intent.getParcelableExtra("tipInfo");
        permission = intent.getStringArrayExtra("permission");
        isShowTip = intent.getBooleanExtra("isShowTip".false); / / directly apply for permission to ActivityCompat. RequestPermissions (this permission, PERMISSION_REQUEST_CODE); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Some vendors' mobile systems may reject authorization if the authorization is successful, so use PermissionChecker to check againif (requestCode == PERMISSION_REQUEST_CODE && isGranted(grantResults)
                && hasPermission(this, permissions)) {
            OnPermissionCallback listener = listenersMap.remove(key);
            if(listener ! = null) { listener.onSuccess(permission); } finish(); }else if (isShowTip) {
            showMissingPermissionDialog();
        } else{// permissionsRefused(); }} // Display permission denied dialog box private voidshowMissingPermissionDialog() {
        if (tipInfo == null) {
            tipInfo = PermissionTipInfo.newInstance();
        }

        new AlertDialog.Builder(this).setTitle(tipInfo.getTitle()).setMessage(tipInfo.getMessage())
                .setNegativeButton(tipInfo.getCancelText(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        permissionsRefused();
                    }
                })
                .setPositiveButton(tipInfo.getOkText(), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        intent.setData(Uri.parse("package:" + getPackageName()));
                        startActivityForResult(intent, REQUEST_SETTING_CODE);

                    }
                }).setCancelable(false).create().show(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // Go to the Settings page after the setting is complete, ask again to see if the permission is enabledif(requestCode == REQUEST_SETTING_CODE) { ActivityCompat.requestPermissions(this, permission, PERMISSION_REQUEST_CODE); Public static Boolean hasPermission(Context Context, String... permissions) {if (permissions.length == 0) {
            return false;
        }
        for (String per : permissions) {
            int result = PermissionChecker.checkSelfPermission(context, per);
            if(result ! = PermissionChecker.PERMISSION_GRANTED) {return false; }}return true; } // Permission denied callback private voidpermissionsRefused() {
        OnPermissionCallback listener = listenersMap.remove(key);
        if(listener ! = null) { listener.onRefused(permission); } finish(); } private boolean isGranted(@NonNull int... grantResult) {if (grantResult.length == 0) {
            return false;
        }
        for (int result : grantResult) {
            if(result ! = PackageManager.PERMISSION_GRANTED) {return false; }}return true;
    }

    @Override
    protected void onDestroy() { super.onDestroy(); Listenersmap.remove (key); listenerSmap.remove (key); listenerSmap.remove (key); listenerSmap.remove (key); } @Override public voidfinish() { super.finish(); / / remove excessive page animation overridePendingTransition (0, 0); } /*** *@date create time 2018/8/18 21:37 *@author W.yulong *@description Content entity class whose permission is denied */ public static class PermissionTipInfo implements Parcelable {private String title ="Warm reminder";
        private String message = "The current application lacks necessary permissions. \n \n Please click \" Settings \"-\" permissions \"- to open the required permissions.;
        private String cancelText = "Cancel";
        private String okText = "Open permissions";

        public PermissionTipInfo(String title, String message, String cancelText, String okText) {
            this.title = title;
            this.message = message;
            this.cancelText = cancelText;
            this.okText = okText;
        }

        public PermissionTipInfo() {
        }

        public static PermissionTipInfo newInstance() {
            return new PermissionTipInfo();
        }

        public String getTitle() {
            return title;
        }

        public PermissionTipInfo setTitle(String title) {
            this.title = title;
            return this;
        }

        public String getMessage() {
            return message;
        }

        public PermissionTipInfo setMessage(String message) {
            this.message = message;
            return this;
        }

        public String getCancelText() {
            return cancelText;
        }

        public PermissionTipInfo setCancelText(String cancelText) {
            this.cancelText = cancelText;
            return this;
        }

        public String getOkText() {
            return okText;
        }

        public PermissionTipInfo setOkText(String okText) {
            this.okText = okText;
            return this;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(this.title);
            dest.writeString(this.message);
            dest.writeString(this.cancelText);
            dest.writeString(this.okText);
        }

        protected PermissionTipInfo(Parcel in) {
            this.title = in.readString();
            this.message = in.readString();
            this.cancelText = in.readString();
            this.okText = in.readString();
        }

        public static final Parcelable.Creator<PermissionTipInfo> CREATOR = new Parcelable.Creator<PermissionTipInfo>() {
            @Override
            public PermissionTipInfo createFromParcel(Parcel source) {
                return new PermissionTipInfo(source);
            }

            @Override
            public PermissionTipInfo[] newArray(int size) {
                returnnew PermissionTipInfo[size]; }}; } /*** *@date create time 2018/8/18 21:27 *@author W.yulong *@description The implementation class of the callback interface, Public static class OnPermissionCallbackImpl implements OnPermissionCallback {@override public Void onSuccess(String[] permission) {} @override public void onRefused(String[] permission) {}} /*** *@date Creation time *@author Public interface OnPermissionCallback {void onSuccess(String[] permission); void onRefused(String[] permission); }}Copy the code


2, in your AndroidManifest.xmlAdd the following registration declaration to the file

<activity android:name="{the name of the Java package in which your PermissionsUtil class resides}.PermissionsUtil"
android:theme="@style/transparentTheme"/>Copy the code

For example, if your APP package is called com.android.demo and PermissionsUtil is in the permission package, then you are in

The androidmanifest.xml file adds the following registration declaration for this class:

<activity android:name="com.android.demo.permission.PermissionsUtil"
android:theme="@style/transparentTheme"/>Copy the code

3. Then define the transparent theme in the style.xml file

<style name="transparentTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@color/color_0000</item>
    <item name="android:windowIsTranslucent">true</item>
</style>Copy the code


And you’re done. Then the specific usage is as follows:

String[] requestPermission = {manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, }; PermissionsUtil.requestPermission(this, requestPermission, new PermissionsUtil.OnPermissionCallbackImpl() {
            @Override
            public void onSuccess(String[] permission) {
                System.out.println("Permission application successful");
            }

            @Override
            public void onRefused(String[] permission) {
                System.out.println("Permission denied."); }});Copy the code

The renderings are as follows:



There are also two other method calls, which are described in comments to the code.