安卓权限

前言

在很久以前,即 Android 6.0 (API 23) 得时候。
应用的权限只要你在AndroidManifest.xml文件中注册权限,安装时则会全部授予,需要的时候 自动唤起授权弹窗询问用户。

但后来,在 Android 6.0 或更高版本对权限进行了分类,对某些涉及到用户隐私的高危权限,不单单要在AndroidManifest.xml文件中注册权限,还要根据用户的需要动态授予(即手动唤起授权弹窗询问用户)。

另外 用户同意过的危险权限还可以在设置中进行修改,比如再次手动授权和取消授权。

正常权限
涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。这些权限在应用安装时授予,运行时不再询问用户。例如: 网络访问、WIFI状态、音量设置等。

危险权限
涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如: 读取通讯录、读写存储器数据、获取用户位置、摄像头、录音等。如果应用声明需要这些危险权限,则必须在运行时明确告诉用户,让用户手动授予。

具体权限列表可以去看看官网权限介绍

动态申请权限

首先需要 在AndroidManifest.xml清单中,列出所需权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!--    权限start-->
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <!--    权限start-->

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/Theme.BlutoothList"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

单个权限

页面布局activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <LinearLayout
        android:layout_width="409dp"
        android:layout_height="100dp"
        android:orientation="vertical"
        android:gravity="center"
        tools:ignore="MissingConstraints">

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取相机权限" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取录音权限" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

页面逻辑MainActivity.java

package com.example.blutoothlist;

import android.Manifest;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

public class MainActivity extends AppCompatActivity {
    private final int PERMISSIONS_CODE_CAMERA = 0;
    private final int PERMISSIONS_CODE_RECORD_AUDIO = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //监听按钮点击
        Button btn1 = findViewById(R.id.button1);
        Button btn2 = findViewById(R.id.button2);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 动态获取权限
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSIONS_CODE_CAMERA);
            }
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 动态获取权限
                // if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {// 如果没有开启蓝牙权限 在开启}
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, PERMISSIONS_CODE_RECORD_AUDIO);
            }
        });
    }

    /**
     * @param requestCode  权限申请组id 自定义的
     * @param permissions  申请权限组内容 是个数组
     * @param grantResults 存储着权限授权结果 也是个数组
     * @deprecated grantResults和permissions一一对应, 被拒绝则为-1,被同意则为0
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PERMISSIONS_CODE_CAMERA:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "获得相机权限成功", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "您拒绝了相机权限", Toast.LENGTH_SHORT).show();
                }
                break;
            case PERMISSIONS_CODE_RECORD_AUDIO:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(this, "获得录音权限成功", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(this, "您拒绝了录音权限", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}

效果

权限组

页面布局activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <LinearLayout
        android:layout_width="409dp"
        android:layout_height="100dp"
        android:orientation="vertical"
        android:gravity="center"
        tools:ignore="MissingConstraints">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="获取相机和录音权限" />
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

页面逻辑MainActivity.java

package com.example.blutoothlist;

import android.Manifest;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private final int PermissionsCode_CameraAndAudio = 0;

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

        //监听按钮点击
        Button btn = findViewById(R.id.button);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 动态获取权限
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, PermissionsCode_CameraAndAudio);
            }
        });
    }

    /**
     * @param requestCode  权限申请组id 自定义的
     * @param permissions  申请权限组内容 是个数组
     * @param grantResults 存储着权限授权结果 也是个数组
     * @deprecated grantResults和permissions一一对应, 被拒绝则为-1,被同意则为0
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PermissionsCode_CameraAndAudio:
                Map map = new HashMap();
                for (int i = 0; i < permissions.length; i++) {
                    String permission = permissions[i]; // 权限名
                    int permissionResult = grantResults[i]; // 权限结果
                    map.put(permission, permissionResult == PackageManager.PERMISSION_GRANTED ? true : false);
                }
                new AlertDialog.Builder(this)
                        //标题
                        .setTitle("权限组获得权限情况")
                        //内容
                        .setMessage(map.toString())
                        //图标
                        .setIcon(R.mipmap.ic_launcher)
                        .setPositiveButton("确认", null)
                        .create()
                        .show();
                break;
        }
    }
}

效果

posted @ 2023-03-01 12:06  丁少华  阅读(76)  评论(0编辑  收藏  举报