Android 动态申请应用权限

一、概述

Android 6.0 (API 23) 之前应用的权限在安装时全部授予,运行时应用不再需要询问用户。在 Android 6.0 或更高版本对权限进行了分类,对某些涉及到用户隐私的权限可在运行时根据用户的需要动态授予。

Android 6.0以下,在AndroidManifest.xml文件中注册权限即可。
Android 6.0及其以后,既要在AndroidManifest.xml文件中注册,又要动态申请危险权限。

二、Android系统权限

两个最重要保护级别是 正常权限危险权限

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

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

权限组名权限名称
CALENDAR(日历)READ_CALENDAR
WRITE_CALENDAR
CAMERA(相机)CAMERA
CONTACTS(联系人)READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION(位置)ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION
MICROPHONE(麦克风)RECORD_AUDIO
PHONE(手机)READ_PHONE_STATE
CALL_PHONE
ERAD_CALL_LOG
WRITE_CALL_LOG
ADD_VOICEMAIL
USE_SIP
PROCESS_OUTGOING_CALLS
SENSORS(传感器)BODY_SENSORS
SMS(短信)SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS
STORAGE(存储卡)READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

PS: 在 AndroidManifest.xml 声明过的危险权限对应的权限组可以在系统 “设置” -> “应用” -> “应用信息” -> “权限” 中查看,可以手动授权和取消授权。

权限组和权限在Android代码中以 字符串常量 来表示,分别定义在以下两个 静态内部类 的字段中:

  • android.Manifest.permission_group(权限组):
    • Manifest.permission_group.CALENDAR
    • Manifest.permission_group.STORAGE
    • ......
  • android.Manifest.permission(权限):
    • Manifest.permission.READ_CALENDAR
    • Manifest.permission.READ_EXTERNAL_STORAGE
    • ......

三、动态申请权限

首先,需要在AndroidManifest.xml清单中静态申请权限,否则无法动态申请权限

AndroidManifest.xml

<manifest ...>

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

    <application ...>
        ...
    </application>
</manifest>

然后,在java代码中写动态申请权限的逻辑代码

MainActivity.java

import android.Manifest;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {

    /**
     * 读取日历
     * 相机
     * 读取手机联系人
     */
    private String[] permissions = new String[]{
            Manifest.permission.READ_CALENDAR,
            Manifest.permission.CAMERA,
            Manifest.permission.READ_CONTACTS
    };

    private final int MY_REQUEST_CODE = 1000;
    private String TAG = "zhumeng";

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

        PackageManager packageManager = this.getPackageManager();

        PermissionInfo permissionInfo = null;
//        PermissionGroupInfo permissionGroupInfo = null;

        for (int i = 0; i < permissions.length; i++) {
            try {
                permissionInfo = packageManager.getPermissionInfo(permissions[i], 0);
//                permissionGroupInfo = packageManager.getPermissionGroupInfo(permissions[i], 0);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            CharSequence permissionName = permissionInfo.loadLabel(packageManager);
//            CharSequence permissionnGropName = permissionGroupInfo.loadLabel(packageManager);
            if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED){
                // 未获取权限
                Log.i(TAG, "您未获得【" + permissionName + "】的权限 ===>");
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){
                    // 这是一个坑,某些手机弹出提示时没有永不询问的复选框,点击拒绝就默认勾上了这个复选框,而某些手机上即使勾选上了永不询问的复选框也不起作用
                    Log.i(TAG, "您勾选了不再提示【" + permissionName + "】权限的申请");
                } else {
                    ActivityCompat.requestPermissions(this, permissions, MY_REQUEST_CODE);
                }
            } else {
                Log.i(TAG, "您已获得了【" + permissionName + "】的权限");
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PackageManager packageManager = this.getPackageManager();
        PermissionInfo permissionInfo = null;
        for (int i = 0; i < permissions.length; i++) {
            try {
                permissionInfo = packageManager.getPermissionInfo(permissions[i], 0);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
            CharSequence permissionName = permissionInfo.loadLabel(packageManager);
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED){
                Log.i(TAG, "您同意了【" + permissionName + "】权限");
            } else {
                Log.i(TAG, "您拒绝了【" + permissionName + "】权限");
            }
        }
    }
}
  • 0
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android应用中,动态申请位置权限的步骤如下: 1. 在AndroidManifest.xml文件中添加位置权限声明。在`<manifest>`标签内添加以下代码: ```xml <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> ``` 2. 在Activity或Fragment中检查是否已经获取了位置权限。可以使用以下代码检查: ```java if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // 已经获取了位置权限,可以进行相关操作 } else { // 未获取位置权限,需要动态申请 } ``` 3. 如果未获取位置权限,需要向用户解释为什么需要该权限,并请求权限。可以使用以下代码请求权限: ```java ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, requestCode); ``` 其中,`requestCode`是一个整数,用于标识请求权限的唯一标识符。 4. 处理权限请求结果。在Activity或Fragment中重写`onRequestPermissionsResult`方法,根据用户的选择做出相应的处理: ```java @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == requestCode) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意了位置权限,可以进行相关操作 } else { // 用户拒绝了位置权限,需要提示用户手动授权或进行其他处理 } } } ``` 这样就完成了动态申请位置权限的过程。在获取到位置权限之后,可以使用相关API来获取用户的位置信息。记得在进行定位操作前,先检查是否已经获取了位置权限

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值