对于权限来说,有普通权限,危险权限等,对于普通权限,只需要在AndroidManifest.xml中添加一下权限声明就可以了。但是对于危险权限就需要进行运行时权限处理。

这是安卓开发时会用到的权限,需要用到时查找即可

android 运行 keras Android 运行时权限_android


还有危险权限

android 运行 keras Android 运行时权限_ide_02


危险权限在Android6.0就要进行运行时权限处理

我们举一个的危险权限例子:我们申请了打电话和照相两个危险权限

首先在activity_main.xml添加一个按钮:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical">
    <Button
        android:id="@+id/make_call"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Make call"
        tools:ignore="MissingConstraints" />
    <Button
        android:id="@+id/make_camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="make camera"/>

</LinearLayout>

在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.CAMERA"/>

然后修改MainActivity代码:

package com.example.runtimepermissiontest;

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

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //打电话
        Button button=findViewById(R.id.make_call);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            //判断是否授权
               if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)!= PackageManager.PERMISSION_GRANTED){
               //未授权则调用ActivityCompat.requestPermissions()方法
                   ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
               }else{
                   call();
               }
            }
        });
        //相机
        Button button1 = findViewById(R.id.make_camera);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2);
                } else {
                    camera();
                }
            }
        });

    }
    public void call(){
        try{
            Intent intent=new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:10086"));
            startActivity(intent);
        }catch (SecurityException e){
            e.printStackTrace();
        }
    }
     public void camera() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, 0);
    }
//ActivityCompat.requestPermissions()方法调用后的结果返回onRequestPermissionsResult()方法
    @Override
     //这三个参数,首先第一个是个请求码,动态处理权限时,每一种权限会有不同的请求码,我们可以根据请求码在以下的方法中处理需要处理的权限
    //代码注释的部分则是根据何种请求来处理权限 例如:ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, 2);第二个参数就是个permission,也就是下面代码的第二个参数
    //它是根据你要申请的权限请求来分类处理的。
    //以下两种方法都可以,只是处理的参数不同,但目的都一样。
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    //判断申请码
        switch (requestCode){
        //申请码为1代表打电话
            case 1:

/* switch (permissions[0]){
                    case Manifest.permission.CALL_PHONE:
                        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                            call();
                        } else {
                            Toast.makeText(this, "没有电话权限", Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case Manifest.permission.CAMERA:
                        if(grantResults.length>0&&grantResults[1]==PackageManager.PERMISSION_GRANTED){
                            camera();
                        }else {
                            Toast.makeText(this, "没有相机权限", Toast.LENGTH_SHORT).show();
                        }
                        break;
                }*/




            //判断授权结果grantResults中的内容是否为我们申请的权限
                if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                    call();
                }else{
                    Toast.makeText(this,"没有电话权限",Toast.LENGTH_SHORT).show();
                }
                break;
         //申请码为2代表相机
             case 2:
                if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED){
                    camera();
                }else {
                    Toast.makeText(this, "没有相机权限", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}

运行时权限核心就是在程序运行时由用户授权执行某些危险操作

  • 首先我们要判断用户是不是已经给我们授权过了。借助ContextCompat.checkSelfPermission()方法。checkSelfPermission()方法接受两个参数,第一个参数是Context,第二个参数是具体的权限名(比如打电话的就是Manifest.permission.CALL_PHONE,相机就是Manifest.permission.CAMERA)。
  • 然后我们使用方法的返回值和PackageManager.PERMISSION_GRANTED作比较,相等就表明已经授权,不相等就没有授权。
  • 如果已经授权,就简单了,直接执行你想用的权限逻辑就可以(比如代码中的打电话封装在call()方法中),如果没有授权,就需要调用ActivityCompat.requestPermission()方法来向用户申请授权,requestPermission()方法接收3个参数,第一个是Activity实例,第二个参数是String数组,我们把要申请的权限名放在数组即可。第三个是请求码,只要是个唯一值就行。(本代码打电话请求码为1,相机请求码为2)
  • 调用完requestPermission()方法之后,系统会弹出一个权限申请的对话框,然后用户可以选择同意或拒绝我们的权限申请,不论哪种结果,都会回调到onRequestPermissionResult()方法中,而授权的结果则会封装在grantResults参数中。这里我们只需要判断一下最后的授权结果,用户同意就调用申请的权限逻辑(打电话),不同意就失败提示即可。