欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android开发从0到1024基础篇(1)权限申请

程序员文章站 2022-04-21 21:12:50
...

一.概述

*随着Android 6.0普及,权限机制的变化,也给我们程序员编码权限带来变化:
之前,6.0以下的权限,我们只需要在配置清单中声明即可,系统会根据权限声明产生一个权限列表,用户只有在同意之后才能完成app的安装。而在6.0以后,用户可以直接安装,当app需要我们授予不恰当的权限的时候,用户可以予以拒绝.*

二.权限分类

6.0后权限分为,默认权限和敏感权限,并且敏感权限都是分组的,当一组内的权限其中一个被用户授权,同组的其他权限也会同样被用户授权

三,普通原生方法去申请敏感权限

1.声明权限:

在配置清单中声明,和之前一样的步骤

2.检查:

第一个参数:上下文,
第二个参数:用户想要检查的权限
返回结果:是一个int类型的数字
PackageManager.PERMISSION_DENIED(表示拒绝)
PackageManager.PERMISSION_GRANTED(表示授权)

ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)

3.申请

第一个参数是Context;
第二个参数是需要申请的权限的字符串数组;
第三个参数为requestCode,主要用于回调的时候检测。

提示:是支持一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。

ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                requestCode);

4.权限申请回调
首先验证requestCode定位到你的申请,
然后验证grantResults对应于申请的结果(和检查的结果一样),这里的数组对应于申请时的第二个权限字符串数组。如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了~

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {//申请权限时候的请求码
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {

            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//表示权限被授权



            } else {
        //表示权限被拒绝,提示用户去设置中去开启权限即可

            }
            return;
        }
    }
}

至此,自己写申请权限的步骤基本完成,通过观察发现虽然权限处理并不复杂,但是需要编写很多重复的代码,所以目前也有很多库对用法进行了封装
RxPermission讲解RxPermission的git地址
接下来着重记录一下这个库的用法,目的在于自己记录一下加深印象,虽然连接已经写的很清楚了:
1.To use this library your minSdkVersion must be >= 11.
minSdkVersion必须 >= 11。

2.用RxPermissions申请权限,必须在Activity.onCreate()或者View.onFinishInflate()中处理。不能在onResume()中处理,因为onResume()在App的生命周期中可能执行的很频繁。如果在请求权限的时候,App重新启动了(例如屏幕旋转导致的App关闭再重新创建),那么用户的选择(允许 或者 拒绝)将无法发给App

使用步骤:

1,添加依赖:

compile ‘com.tbruyelle.rxpermissions:rxpermissions:[email protected]
或者:
compile ‘com.tbruyelle.rxpermissions2:rxpermissions:[email protected]
区别:
首先该库依赖Rxjava,因为Rxjava有两个版本,

compile'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex.rxjava2:rxjava:2.0.6'

所以它也有俩个版本:
第一个依赖是对RxJava1的依赖版本,第二个依赖是对Rxjava2的依赖,
根据自己实际项目使用rx情况添加依赖:

所以使用权限库需要同时添加对应的Rxjava依赖

2.初始化 RxPermissions

RxPermissions rxPermissions = new RxPermissions(this);

3.使用RxPermissions ,如申请相机权限

3.1 直接申请单个权限使用

 rxPermissions
                .request(Manifest.permission.CAMERA)
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                       if (aBoolean){
                         //权限申请成功
                       }else {
                            //权限申请失败,提示用户去设置中打开权限
                       }


                    }
                });

3.2同时请求多个权限(合并结果注意:当所有权限请求成功会返回true,若有一个权限未成功则返回false。

rxPermissions.
request(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO)
.subscribe(new Action1() {
@Override
public void call(Boolean granted) {
if (granted) { // 在android 6.0之前会默认返回true
// 已经获取全部权限: All requested permissions are granted

    } else {
        // 未获取权限At least one permission is denied

        Toast.makeText(MainActivity.this, "您没有授权该权限,请在设置中打开授权", Toast.LENGTH_SHORT).show();
    }
    }
});

3.3同时请求多个权限(分别获取结果)

如果想要在同时请求多个权限,又想分别获取授权结果的话,可以调用requestEach方法或者ensureEach方法

    rxPermissions
            .requestEach(Manifest.permission.CAMERA,
                    Manifest.permission.RECORD_AUDIO)
            .subscribe(new Action1<Permission>() {
                @Override
                public void call(Permission permission) {
                    if (permission.name.equals(Manifest.permission.CAMERA)) {
                        if (permission.granted) {
                            //权限申请成功
                            Log.e("eeee", "相机权限申请成功");
                        } else {
                            //  未获取权限
                            Toast.makeText(MainActivity.this, "相机权限没有申请成功,请在设置中打开授权", Toast.LENGTH_SHORT).show();
                        }

                    } else if (permission.name.equals(Manifest.permission.RECORD_AUDIO)) {
                        if (permission.granted) {
                            //权限申请成功
                            Log.e("eeee", "录音权限申请成功");
                        } else {
                            //  未获取权限
                            Toast.makeText(MainActivity.this, "录音权限没有申请成功,请在设置中打开授权", Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });

3.4条件触发获取权限(结合RxBinding使用)

首先需要解释一下,RxBinding库是根据其所支持控件在Android平台的位置而单独分离的,并且内部依赖Rxjava或者RxAndroid,所以使用Rxbinding结合RxPermission,只需要依赖:

 compile 'com.tbruyelle.rxpermissions:rxpermissions:0.9.4@aar'
 compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:1.0.0'

当然,添加上:compile'io.reactivex:rxjava:1.1.0'也不会报错,目前个人水平还不知道为什么,但是既然可以不添加,何必再添加上

具体Rxbinding的依赖分类如下:(按照控件的需要添加即可)另外每个库还有对应的Kotlin支持库。

compile 'com.jakewharton.rxbinding:rxbinding:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-support-v4:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-design:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:1.0.0'
compile 'com.jakewharton.rxbinding:rxbinding-leanback-v17:1.0.0'

跑题了…..

依赖成功,接下来就是代码的编写:

 RxView.clicks(btn)
                .throttleFirst(2, TimeUnit.SECONDS)//防止抖动,单位是秒
                .compose(rxPermissions.ensure(Manifest.permission.CAMERA))//权限申请
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        if (aBoolean){
            //申请成功
                            Log.e("eeee","true");
                        }else {
            //申请失败
                            Log.e("eeee","false");

                        }
                    }
                });

注意:权限的声明还是需要在配置清单中进行声明,否者会报错