小白成长记(一)——使用easyPermisions框架申请动态权限

Android M(6.0)以上是动态权限,google官方推出了一个开源项目EasyPermissions 来方便集成动态权限的功能。 

EasyPermissions 的github地址是:https://github.com/googlesamples/easypermissions 。

基本用法

依赖

EasyPermissions 通过在build.gradle写入下面的依赖,来进行安装(现在的最新版本是1.3.0)。

dependencies {
    implementation 'pub.devrel:easypermissions:1.3.0'
}

开始使用

为了开始使用EasyPermissions,你需要在你的Activity (或者Fragment)中重写onRequestPermissionsResult 方法:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

   
}

请求权限

可以让Activity / Fragment实现PermissionCallbacks 接口,如下所示:


public class TestActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List perms) {

    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List perms) {

    }
}

必需权限

有一些案例,如果你的应用没有这些权限,有些功能将不能正常使用。如果用户点击了“不再询问”框,并且拒绝授权权限,你的应用将不能从用户那里获取到权限,除非用户去应用设置里更改状态。在这种情况下,你可以用EasyPermissions.somePermissionPermanentlyDenied(…)这个方法来判断,最终展示一个Dialog,指导用户去系统设置界面,为你的应用开启权限。

/**
     * 请求权限成功
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsGranted(int requestCode, List perms) {
        AppUtil.showTextToast(getApplicationContext(), toast, "用户授权成功");
        for (String str : perms) {
            //遍历你所有申请的权限列表
        }

    }

    /**
     * 请求权限失败
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsDenied(int requestCode, List perms) {
        AppUtil.showTextToast(getApplicationContext(), toast, "用户授权失败----------------------");
        /**
         * 若是在权限弹窗中,用户勾选了'NEVER ASK AGAIN.'或者'不在提示',且拒绝权限。
         * 这时候,需要跳转到设置界面去,让用户手动开启。
         */
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this)
                    .setRationale("没有该权限,此应用程序可能无法正常工作。打开应用设置屏幕以修改应用权限")
                    .setTitle("必需权限")
                    .build()
                    .show();

        }
    }

普通实例 

下面是EasyPermissions的通用动态获取权限的实现方法:

public class BaseActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
    private Toast toast = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        checkWritePermission();
        setContentView(R.layout.activity_base);
    }

    /**
     * 检查读写权限权限
     */
    public boolean checkWritePermission() {
        boolean result = PermissionsUtils.checkPermission(this, Constance.PERMS_WRITE);
        if (!result) {
            PermissionsUtils.requestPermission(this, Constance.WRITE_PERMISSION_TIP, Constance.WRITE_PERMISSION_CODE, Constance.PERMS_WRITE);
        }
        return result;
    }

    /**
     * 重写onRequestPermissionsResult,用于接受请求结果
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //将请求结果传递EasyPermission库处理
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    /**
     * 请求权限成功
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsGranted(int requestCode, List perms) {
        AppUtil.showTextToast(getApplicationContext(), toast, "用户授权成功");
        for (String str : perms) {
            //遍历你所有申请的权限列表
        }

    }

    /**
     * 请求权限失败
     *
     * @param requestCode
     * @param perms
     */
    @Override
    public void onPermissionsDenied(int requestCode, List perms) {
        AppUtil.showTextToast(getApplicationContext(), toast, "用户授权失败----------------------");
        /**
         * 若是在权限弹窗中,用户勾选了'NEVER ASK AGAIN.'或者'不在提示',且拒绝权限。
         * 这时候,需要跳转到设置界面去,让用户手动开启。
         */
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this)
                    .setRationale("没有该权限,此应用程序可能无法正常工作。打开应用设置屏幕以修改应用权限")
                    .setTitle("必需权限")
                    .build()
                    .show();

        }
    }
}

MainActivity去调用如下:

public class MainActivity extends BaseActivity {
    private Button btn_photo;
    private ImageView img;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_photo = ((Button) findViewById(R.id.photo));
        img = ((ImageView) findViewById(R.id.img));
        btn_photo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkWritePermission()) {
                    Intent intent = null;
                    intent = new Intent();
                    // 指定开启系统相机的Action
                    intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.addCategory(Intent.CATEGORY_DEFAULT);
                    startActivityForResult(intent, 1);
                } else {
                    PermissionsUtils.requestPermission(MainActivity.this, Constance.WRITE_PERMISSION_TIP, Constance.WRITE_PERMISSION_CODE, Constance.PERMS_WRITE);
                }
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && data != null) {
            Bitmap bitmap = (Bitmap) data.getExtras().get("data");
            img.setImageBitmap(bitmap);
        }
    }
}

附一个简单的封装类

public class PermissionsUtils {
    /**
     *
     * @param context
     * return true:已经获取权限
     * return false: 未获取权限,主动请求权限
     */
    // @AfterPermissionGranted 是可选的
    public static boolean checkPermission(Activity context, String[] perms) {
        return EasyPermissions.hasPermissions(context, perms);
    }
    /**
     * 请求权限
     * @param context
     */
    public static void requestPermission(Activity context,String tip,int requestCode,String[] perms) {
        EasyPermissions.requestPermissions(context, tip,requestCode,perms);
    }
}
public class Constance {
    /**
     * 写入权限的请求code,提示语,和权限码
     */
    public final static int WRITE_PERMISSION_CODE = 110;
    public final static String WRITE_PERMISSION_TIP = "为了正常使用,请允许读写权限!";
    public final static String[] PERMS_WRITE = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION};
}

结束语

1.一定要记得要先在AndroidManifest.xml声明权限。 

2.申请权限数组的时候不要去申请Manifest.permission_group.xxxxx;要用它的子类去申请极限权限。

附加: 自己封装的PermisionsUtils 

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
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 java.util.ArrayList;
import java.util.List;

/**
 * Created by Sincerity on 2018/10/24.
 * 描述:
 */
public class PermissionsUtils {
    public static final int mRequestCode = 100;//权限请求码
    public static boolean showSystemSetting = true;

    private PermissionsUtils() {
    }

    private static PermissionsUtils permissionsUtils;
    private IPermissionsResult mPermissionsResult;

    public static PermissionsUtils getInstance() {
        if (permissionsUtils == null) {
            permissionsUtils = new PermissionsUtils();
        }
        return permissionsUtils;
    }

    public void chekPermissions(Activity context, String[] permissions, @NonNull IPermissionsResult permissionsResult) {
        mPermissionsResult = permissionsResult;

        if (Build.VERSION.SDK_INT < 23) {//6.0才用动态权限
            permissionsResult.passPermissons();
            return;
        }

        //创建一个mPermissionList,逐个判断哪些权限未授予,未授予的权限存储到mPerrrmissionList中
        List mPermissionList = new ArrayList<>();
        //逐个判断你要的权限是否已经通过
        for (int i = 0; i < permissions.length; i++) {
            if (ContextCompat.checkSelfPermission(context, permissions[i]) != PackageManager.PERMISSION_GRANTED) {
                mPermissionList.add(permissions[i]);//添加还未授予的权限
            }
        }

        //申请权限
        if (mPermissionList.size() > 0) {//有权限没有通过,需要申请
            ActivityCompat.requestPermissions(context, permissions, mRequestCode);
        } else {
            //说明权限都已经通过,可以做你想做的事情去
            permissionsResult.passPermissons();
            return;
        }


    }

    //请求权限后回调的方法
    //参数: requestCode  是我们自己定义的权限请求码
    //参数: permissions  是我们请求的权限名称数组
    //参数: grantResults 是我们在弹出页面后是否允许权限的标识数组,数组的长度对应的是权限名称数组的长度,数组的数据0表示允许权限,-1表示我们点击了禁止权限

    public void onRequestPermissionsResult(Activity context, int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        boolean hasPermissionDismiss = false;//有权限没有通过
        if (mRequestCode == requestCode) {
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == -1) {
                    hasPermissionDismiss = true;
                }
            }
            //如果有权限没有被允许
            if (hasPermissionDismiss) {
                if (showSystemSetting) {
                    showSystemPermissionsSettingDialog(context);//跳转到系统设置权限页面,或者直接关闭页面,不让他继续访问
                } else {
                    mPermissionsResult.forbitPermissons();
                }
            } else {
                //全部权限通过,可以进行下一步操作。。。
                mPermissionsResult.passPermissons();
            }
        }

    }


    /**
     * 不再提示权限时的展示对话框
     */
    AlertDialog mPermissionDialog;

    private void showSystemPermissionsSettingDialog(final Activity context) {
        final String mPackName = context.getPackageName();
        if (mPermissionDialog == null) {
            mPermissionDialog = new AlertDialog.Builder(context)
                    .setMessage("系统没有得到权限,无法正常运行,请手动授予")
                    .setPositiveButton("打开设置", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            cancelPermissionDialog();
                            Uri packageURI = Uri.parse("package:" + mPackName);
                            Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, packageURI);
                            context.startActivityForResult(intent, mRequestCode);
                        }
                    })
                    .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //关闭页面或者做其他操作
                            cancelPermissionDialog();
                            //mContext.finish();
                            mPermissionsResult.forbitPermissons();
                        }
                    })
                    .create();
        }
        mPermissionDialog.setCancelable(false);
        mPermissionDialog.show();
    }

    //关闭对话框
    private void cancelPermissionDialog() {
        if (mPermissionDialog != null) {
            mPermissionDialog.cancel();
            mPermissionDialog = null;
        }

    }


    public interface IPermissionsResult {
        void passPermissons();

        void forbitPermissons();
    }
}

使用方法: 在Activity ------> oncreate方法中调用

// this 当前对象
// permissions 你所要请求的权限数组
// 信息回调
PermissionsUtils.getInstance().chekPermissions(this, permissions, permissionsResult);

 PermissionsUtils.IPermissionsResult permissionsResult = new PermissionsUtils.IPermissionsResult() {
        //所有权限通过
        @Override
        public void passPermissons() {
}
 //部分权限不通过
        @Override
        public void forbitPermissons() {
            //finish();
            Toast.makeText(LoginActivity.this, "权限不通过!", Toast.LENGTH_SHORT).show();
        }
    };

重写Activity的 onRequestPermissionsResult()方法

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionsUtils.getInstance().onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

最后监听Activity的 onActivityResult()方法

如果    requestCode == PermissionsUtils.mRequestCode; 

再次执行PermissionsUtils.getInstance().chekPermissions(this, permissions, permissionsResult);即可

经测试 完美支持6.0.7.0 8.0 系统 
 

 

你可能感兴趣的:(学习笔记)