Android 6.0以上动态申请权限

Posted by Don on March 1, 2017

话不多说,直接上代码

package cn.rjgc.project.util;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.databinding.ViewDataBinding;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.view.KeyEvent;

import java.util.ArrayList;
import java.util.List;

import cn.rjgc.project.base.BaseActivity;
import cn.rjgc.project.base.BaseActivityViewModel;

import static android.Manifest.permission.ACCESS_NETWORK_STATE;
import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.READ_PHONE_STATE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

/**
 * 继承了BaseActivity,实现Android6.0的运行时权限检测
 * 需要进行运行时权限检测的Activity可以继承这个类
 *
 *来源于 工程APP
 */
public abstract class CheckPermissionActivity<DB extends ViewDataBinding,VM extends BaseActivityViewModel> extends BaseActivity<DB,VM> implements
        ActivityCompat.OnRequestPermissionsResultCallback {

    //需要进行监测的权限数组
    protected String[] needPermissions = {
            WRITE_EXTERNAL_STORAGE,
            READ_EXTERNAL_STORAGE,
            INTERNET,
            ACCESS_NETWORK_STATE,
            READ_PHONE_STATE
    };

    private static final int PERMISSION_REQUESTCODE = 0;

    //判断是否需要监测,防止不停的弹窗
    private boolean isNeedCheck = true;

    @Override
    protected void onResume() {
        super.onResume();
        //当系统版本低于android_M(6.0)时,跳过权限检查,只有大于等于android_M才需要动态申请权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (isNeedCheck) {
                checkPermissions(needPermissions);
            }
        }
    }

    private void checkPermissions(String... permissions) {
        List<String> needRequestPermissionList = findDeniedPermissions(permissions);
        if (needRequestPermissionList != null &&
                needRequestPermissionList.size() > 0) {
            //申请权限
            ActivityCompat.requestPermissions(this,needRequestPermissionList.toArray(
                    new String [needRequestPermissionList.size()]), PERMISSION_REQUESTCODE);
        }
    }

    /**
     * 获取需要申请的权限列表
     * @param permissions 程序想要申请的所有权限
     * @return 用户拒绝的权限
     */
    private List<String> findDeniedPermissions(String[] permissions) {
        List<String> needRequestPermissionList = new ArrayList<>();
        for (String perm : permissions) {
            //判断用户是否拒绝了该权限
            if (ContextCompat.checkSelfPermission(this, perm) !=
                    PackageManager.PERMISSION_GRANTED ||
                    ActivityCompat.shouldShowRequestPermissionRationale(this,perm)) {
                //shouldShowRequestPermissionRationale ==> 是否需要调用系统的权限申请界面
                needRequestPermissionList.add(perm);
            }
        }
        return needRequestPermissionList;
    }

    //监测是否所有的权限都已授权
    private boolean verifyPermissions(int[] grantResults) {
        boolean res = true;
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                res = false;
            }
        }
        return res;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUESTCODE) {
            if (!verifyPermissions(grantResults)) {
                showMissingPermissionDialog();
                isNeedCheck = false;
            }
        }
    }

    //提示框
    private void showMissingPermissionDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("提示");
        builder.setMessage("当前应用缺少必要权限,有可能会影响程序正常使用。请点击'设置-‘权限’-打开所需权限'");
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
//                finish();
            }
        });

        builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                startAppSettings();
            }
        });
        builder.setCancelable(false);
        builder.show();

    }

    //跳转手机设置界面
    private void startAppSettings() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            this.finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}

此类是基于mvvm模式编写,并继承了baseActivity,只需将需要进行运行时权限检测的Activity继承这个类即可