Android运行时权限方案全解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lijizhi19950123/article/details/78563145

Android权限适配方案

(一) 6.0之前的版本权限处理方案

第一步: 在AndroidManifest中申明所需要的所有权限

第二步: 在用户安装App时,展示所有需要授权的程序

第三步: 用户同意授权即可安装App,反之则无法安装app

(二) 6.0版本的权限处理方案

6.0这个版本开始出现了动态申请权限这个概念

为什么会出现这个概念呢?

首先我们就必须知道权限的分类,从整体的角度可以把权限分为两大类。

一种是指普通的权限,一种是指危险权限。

那么普通权限和危险权限的本质区别是什么呢?

在我查阅相关的权限资料后,我发现普通权限与危险权限最本质的区别是是否涉及用户隐私信息的读取
危险权限主要以组的形式进行分类,以下我列出的9组都为危险权限(需要动态申请的权限),其余没有列出的就都为普通权限
身体传感器,日历,摄像头,通讯录,地理位置,麦克风,电话,短信,存储空间
这里写图片描述

不用第三方依赖的处理方式

第一步:在AndroidManifest中申明所需要的权限,这个和之前的版本处理是一致

第二步:检查权限,代码如下所示:

   if (ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_CONTACTS)
       
     != PackageManager.PERMISSION_GRANTED) {
     }else{
     //
  }   

这里涉及到一个API,ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。

第三步:申请授权,代码如下所示:

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

该方法为异步,第一个参数传入的是一个Context,第二个参数是需要申请权限的字符串数组,第三个参数为请求码,主要用于接口回调,从方法名以及第二个参数可以看出是支持一次性申请多个权限的。

第四步: 处理权限接口回调

 @Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
     switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // I如果请求取消,则
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

               } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
              }
            return;
         }
       }
    }

第五步:小结

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

第六步: 当用户在第一次授权时选择拒绝,你又需要和用户说明为什么需要这个权限时调用以下方法

if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) 

第七步:将上述步骤连接起来就是一个完整的权限处理

// Context为当前Activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {

    // 
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        //弹出解释对话框给用户
        //等待用户响应
        // 用户看到解释再次提出请求
    } else {

        // 不需要解释对话框,直接请求权限

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

      
    }
}

第八步:范例代码

package com.example.dell.runtimerequestpermessiondemo;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton= findViewById(R.id.btn_1);
        testCall( mButton);
    }

    public void testCall(View view) {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CALL_PHONE},
                    MY_PERMISSIONS_REQUEST_CALL_PHONE);
        } else {
            callPhone();
        }
    }

    public void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + "10086");
        intent.setData(data);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

        if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                callPhone();
            } else {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

使用开源库

PermissionsDispatcher
具体用法可以从自行上Github上查阅相关文档

猜你喜欢

转载自blog.csdn.net/lijizhi19950123/article/details/78563145