前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android 6.0申请权限工具类

Android 6.0申请权限工具类

原创
作者头像
CatEatFish
修改2020-07-09 14:20:32
1.2K0
修改2020-07-09 14:20:32
举报
文章被收录于专栏:干活分享干活分享干活分享

android 6.0以后,新增加了动态申请权限这一要求,具体是怎么回事呢?

1.概述

  • 关于运行时权限 在Android6.0开始,App可以直接安装,App在运行时一个一个询问用户授予权限,系统会弹出一个对话框让用户选择是否授权某个权限给App(这个Dialog不能由开发者定制),当App需要用户授予不恰当的权限的时候,用户可以拒绝,用户也可以在设置页面对每个App的权限进行管理。 特别注意:这个对话框不是开发者调用某个权限的功能时由系统自动弹出,而是需要开发者手动调用,如果你直接调用而没有去申请权限的话,将会导致App崩溃。
  • 哪些权限需要动态申请 正常权限: 使用时直接在清单文件中声明即可。
    正常权限.jpg
    正常权限.jpg

危险权限: 使用时需要动态申请权限。

危险权限.jpg
危险权限.jpg

2.申请权限工具类

申请权限的流程:

1.判断是否是 Android 6.0以上

 2.判断权限(危险权限)是否申请了
 3.没有申请,去申请                                  

######1.定义权限申请回掉接口

public interface PermissionListener {
    // 申请成功
    public void onSucceed();
    // 申请失败
    public void onFiled();
}

######2.申请权限的工具类

public class PermissionUtils {

    //判断版本是否是6.0
    public static boolean isVersionCodeM() {
        return Build.VERSION.SDK_INT > Build.VERSION_CODES.M;
    }
    /**
     *
     * @param context
     * @param permissions
     * @return 获取未授权的集合
     */
    public static List<String> getDeniedList(Context context,String... permissions){
        //创建一个未授权的集合
        List<String> deniedList =new ArrayList<>();
        //如果传入为null,返回空的集合
        if (permissions.length==0) {
            return deniedList;
        }
        for (String permission : permissions) {
            int permissionCode = ContextCompat.checkSelfPermission(context, permission);
            if (permissionCode== PackageManager.PERMISSION_DENIED) {
                //将没有授权的添加到集合
                deniedList.add(permission);
            }
        }
        return deniedList;
    }
}

######3.申请权限的帮助类 (无界面的fragment)

public class PermissionFragment extends Fragment {
    private static final int REQUESTCODE = 66;
    private static final int REQUEST_PERMISSION_SETTING = 55;
    private PermissionListener mPermissionListener;
    private Activity mActivity;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //  Fragment具有属性retainInstance,默认值为false。当设备旋转时,fragment会随托管activity一起销毁并重建。调用setRetainInstance(true)方法可保留fragment,
        setRetainInstance(true);
    }

    public void setPermissionListener(PermissionListener permissionListener) {
        this.mPermissionListener = permissionListener;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public void requestPermissions(Activity activity, String[] permission) {
        this.mActivity = activity;
        requestPermissions(permission, REQUESTCODE);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUESTCODE) {
            // 获取未申请的权限列表
            List<String> deniedPermissions = PermissionUtils.getDeniedList(mActivity, permissions);
            if (deniedPermissions.size() > 0) {
                // 执行失败的方法
                onFailed(permissions);
            } else {
                // 执行成功的方法
                onSucceed();
            }
        }

    }

    /**
     * 成功时回调方法
     */
    private void onSucceed() {
        if (mPermissionListener != null) {
            mPermissionListener.onSucceed();
        }

    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void onFailed(String[] permissions) {
        for (int i = 0; i < permissions.length; i++) {
            // 用户拒绝是true   用户选择不再提示是:false
            if (!shouldShowRequestPermissionRationale(permissions[i])) {
                new AlertDialog.Builder(mActivity)
                        .setTitle("权限被拒绝")
                        .setMessage("权限管理-->打开拒绝的权限")
                        .setPositiveButton("去打开", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                openSetting();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                                mPermissionListener.onFiled();
                            }
                        })
                        .show();
                return;
            }
        }
        mPermissionListener.onFiled();
    }

    /**
     * 打开应用设置页面
     */
    private void openSetting() {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", mActivity.getPackageName(), null);
        intent.setData(uri);
        startActivityForResult(intent, REQUEST_PERMISSION_SETTING);
    }

    @Override
    public void onDestroy() {
        // 销毁对象,防止内存泄漏
        mActivity = null;
        mPermissionListener = null;
        super.onDestroy();

    }
}

######4.申请权限的帮助类

/**
 * Created by LiMing on 2018/4/25.
 * QQ:1002464056
 * Email: 1002464056@qq.com
 * Version:1.0
 */

public class XPermission {

    private Activity mActivity;
    private PermissionFragment mPermissionFragment;
    private static final String TAG = "XPermission";
    private String[] mPermissions;

    public XPermission(Activity activity) {
        this.mActivity = activity;
        mPermissionFragment = getPermissionFragment(activity);
    }

    private PermissionFragment getPermissionFragment(Activity activity) {
        //获取权限的fragment
        PermissionFragment permissionFragment = findPermissionFragment(activity);
        boolean isNewInstance = (permissionFragment == null);
        if (isNewInstance) {
            permissionFragment = new PermissionFragment();
            FragmentManager fragmentManager = activity.getFragmentManager();
            fragmentManager.beginTransaction()
                    .add(permissionFragment, TAG)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();

        }
        return permissionFragment;
    }

    /**
     * 获取权限fragment
     *
     * @param activity
     * @return
     */
    private PermissionFragment findPermissionFragment(Activity activity) {
        return (PermissionFragment) activity.getFragmentManager().findFragmentByTag(TAG);
    }

    /**
     * 要申请的权限组
     *
     * @param permissions
     * @return
     */
    public XPermission permissions(String... permissions) {
        mPermissions = permissions;
        return this;
    }

    /**
     * 申请权限
     *
     * @param permissionListener
     */
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void request(PermissionListener permissionListener) {
        mPermissionFragment.setPermissionListener(permissionListener);
        // 1.判断版本
        if (!PermissionUtils.isVersionCodeM()) {
            // 版本6.0一下,直接回调成功方法
            permissionListener.onSucceed();
            return;
        }
        // 版本6.0及以上
        // 2.获取未授权的列表
        List<String> deniedList = PermissionUtils.getDeniedList(mActivity, mPermissions);
        if (deniedList.size() > 0) {
            // 3.去申请权限
            mPermissionFragment.requestPermissions(mActivity, deniedList.toArray(new String[deniedList.size()]));
        } else {
            permissionListener.onSucceed();
        }


    }

}

######5.在MainActivity中调用

public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
    }
    //点击事件
    @RequiresApi(api = Build.VERSION_CODES.M)
    public void click(View view) {
        new XPermission(this)
                .permissions(Manifest.permission.CAMERA)
                .request(new PermissionListener() {
                    @Override
                    public void onSucceed() {
                        // TODO
                        Toast.makeText(MainActivity.this,"授权成功",Toast.LENGTH_SHORT).show();
                    }
                    @Override
                    public void onFiled() {
                        Toast.makeText(MainActivity.this,"授权失败",Toast.LENGTH_SHORT).show();
                    }
                });
    }
}

简单的封装基本可以满足使用,代码易懂,有特殊需求完全可以去二次封装,附上链接地址https://github.com/CatEatFishs/XPermission/tree/v1.0

感谢@刘付文 的博客

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.概述
  • 2.申请权限工具类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档