前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android的单个或多个权限动态申请

Android的单个或多个权限动态申请

作者头像
夜雨飘零
发布2020-05-06 11:48:27
3.8K0
发布2020-05-06 11:48:27
举报
文章被收录于专栏:CSDN博客CSDN博客

原文博客:Doi技术团队 链接地址:https://blog.doiduoyi.com/authors/1584446358138 初心:记录优秀的Doi技术团队学习经历

前言

在Android 6.0(API 级别 23)以下申请权限是非常简单的,直接在AndroidManifest.xml这个配置文件中加入申请权限的列表就可以了,比如我要申请四个权限,如下:

代码语言:javascript
复制
<!--打电话-->
<uses-permission android:name="android.permission.CALL_PHONE" />
<!--使用相机-->
<uses-permission android:name="android.permission.CAMERA" />
<!--写入内存卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读取内存卡-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

但是在Android 6.0(API 级别 23)以上的版就不可以这样申请了,因为这样申请权限对用户来说是非常危险的,应用已安装就获取了全部权限,也不知道这些权限应用要来干什么,可能是用户不希望发生的一些操作。所以在Android 6.0之后,一些危险的权限就要动态申请了,哪些是危险权限呢,下面是官方提供的一个需要动态申请的危险权限:

权限组

权限

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 • READ_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

如果要使用上面的权限,除了要在AndroidManifest.xml这个配置文件声明,还要在Java代码中增加动态申请。下面我们就介绍如何单个和多个权限动态申请。

单个权限的动态申请

比如我们的应用要打电话,打电话是一个危险权限.

  • 首先需要动态申请AndroidManifest.xml配置文件添加申请打电话权限的声明,如下:
代码语言:javascript
复制
<!--打电话-->
<uses-permission android:name="android.permission.CALL_PHONE" />
  • 然后在Java代码中编写一个动态申请打电话权限的方法,当我们需要打电话之前,先要调用这个方法获取权限:
代码语言:javascript
复制
// 请求单个权限
private void request_permission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
            != PackageManager.PERMISSION_GRANTED) {
        // 最后的请求码是对应回调方法的请求码
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.CALL_PHONE}, 1001);
    } else {
        Toast.makeText(this, "你已经有权限了,可以直接拨打电话", Toast.LENGTH_LONG).show();
    }
}
  • 请求申请权限之后,当用户同意或者拒绝权限之后,都会在请求权限的回调方法反馈,我们可以在这个回调方法中判断是否已经授权,并做相关的操作:
代码语言:javascript
复制
// 请求权限回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case 1001:
            // 1001的请求码对应的是申请打电话的权限
            // 判断是否同意授权,PERMISSION_GRANTED 这个值代表的是已经获取了权限
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(MainActivity.this, "你同意授权,可以打电话了", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(MainActivity.this, "你不同意授权,不可以打电话", Toast.LENGTH_LONG).show();
            }
            break;
    }
}
  • 我们增加一个按钮,让这个按钮的点击事件调用我们的申请权限方法:
代码语言:javascript
复制
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button request_permission_btn = (Button) findViewById(R.id.request_permission_btn);

    // 点击获取单个权限
    request_permission_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            request_permission();
        }
    });
}
  • activity_main中的界面代码如下:
代码语言:javascript
复制
<?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"
    android:orientation="vertical"
    tools:context="com.yeyupiaoling.testpermission.MainActivity">

    <Button
        android:id="@+id/request_permission_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请求单个权限" />
</LinearLayout>
  • 测试我们的程序,第二个按钮时下一部分的,读者目前可以不用理会。第一次申请的时候是没有权限的,然后就会动态申请权限,用户同意了就获得了权限。第二次申请权限时,因为第一次已经申请到了,所以可以直接使用了。
这里写图片描述
这里写图片描述

多个权限动态申请

  • 多个权限申请也是一样的,首先同样需要动态申请AndroidManifest.xml配置文件添加所有申请的权利,如下。值得注意的是WRITE_EXTERNAL_STORAGEREAD_EXTERNAL_STORAGE都是属于STORAGE组的,在申请它们两个的时候吗,只要同意一个,系统会立即另外一个权限,不会再弹出权限授予询问的对话框。
代码语言:javascript
复制
<!--使用相机-->
<uses-permission android:name="android.permission.CAMERA" />
<!--写入内存卡-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读取内存卡-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 多个权限的申请就复杂一些,首先要先创建一个列表,把需要的申请的权限添加到这个列表中,最后统一提交申请:
代码语言:javascript
复制
// 请求多个权限
private void request_permissions() {
    // 创建一个权限列表,把需要使用而没用授权的的权限存放在这里
    List<String> permissionList = new ArrayList<>();

    // 判断权限是否已经授予,没有就把该权限添加到列表中
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
        permissionList.add(Manifest.permission.CAMERA);
    }

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
    }

    // 如果列表为空,就是全部权限都获取了,不用再次获取了。不为空就去申请权限
    if (!permissionList.isEmpty()) {
        ActivityCompat.requestPermissions(this,
                permissionList.toArray(new String[permissionList.size()]), 1002);
    } else {
        Toast.makeText(this, "多个权限你都有了,不用再次申请", Toast.LENGTH_LONG).show();
    }
}
  • 申请多个权限,在回调方法中也会反馈多个权限的申请结果,所以我们要判断每个权限的申请结果,全部的权限都申请成功了,那才是申请成功了:
代码语言:javascript
复制
// 请求权限回调方法
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case 1002:
            // 1002请求码对应的是申请多个权限
            if (grantResults.length > 0) {
                // 因为是多个权限,所以需要一个循环获取每个权限的获取情况
                for (int i = 0; i < grantResults.length; i++) {
                    // PERMISSION_DENIED 这个值代表是没有授权,我们可以把被拒绝授权的权限显示出来
                    if (grantResults[i] == PackageManager.PERMISSION_DENIED){
                        Toast.makeText(MainActivity.this, permissions[i] + "权限被拒绝了", Toast.LENGTH_SHORT).show();
                    }
                }
            }
            break;
    }
}
  • 我们同样增加一个按钮,让这个按钮的点击事件调用我们的申请多个权限方法:
代码语言:javascript
复制
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button request_permissions_btn = (Button) findViewById(R.id.request_permissions_btn);

    // 点击获取多个权限
    request_permissions_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            request_permissions();
        }
    });
}
  • activity_main中的界面代码如下:
代码语言:javascript
复制
<?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"
    android:orientation="vertical"
    tools:context="com.yeyupiaoling.testpermission.MainActivity">

    <Button
        android:id="@+id/request_permissions_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="请求多个权限" />
</LinearLayout>
  • 效果展示,当我们点击按钮申请多个权限时,就会开始申请多个权限。如上面所说的读取内存卡和写入内存卡属于一个组,所以我们在看到关于内存卡的只是申请一次,如果一个拒绝了,那就全部都拒绝了。
这里写图片描述
这里写图片描述

参考资料

  1. https://developer.android.com/guide/topics/security/permissions#normal-dangerous
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-07-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 单个权限的动态申请
  • 多个权限动态申请
  • 参考资料
相关产品与服务
访问管理
访问管理(Cloud Access Management,CAM)可以帮助您安全、便捷地管理对腾讯云服务和资源的访问。您可以使用CAM创建子用户、用户组和角色,并通过策略控制其访问范围。CAM支持用户和角色SSO能力,您可以根据具体管理场景针对性设置企业内用户和腾讯云的互通能力。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档