Android动态获取权限(详细教程附代码)

news2024/11/15 15:41:22

Android动态获取权限

  • 概述
  • 动态获取权限
  • 具体实现
    • layout布局代码
    • 回调函数onRequestPermissionsResult
    • 权限判断工具类
    • 清单文件
    • 方式一:懒汉式
    • 方式二:饿汉式

概述

如果是android6.0以下的版本,只需要在manifest声明对应的权限即可。但是这样会大大降低系统的安全性。所以在android6.0及其以后,app获取权限需要得到用户的反馈才可以。

动态获取权限

动态获取权限,可以分为两种情况。情况一,操作到app特定的功能,需要某些权限时进行动态获取,这种情况即为“懒汉式”获取。情况二,在初始情况时(在onCreate中获取),直接获取到所有需要的权限,这种情况即为“饿汉式”。

具体实现

比如某个app在使用的时候需要获取到到通讯录读写权限,短信读取发送权限。

注意:读通讯录是一个权限,写通讯录是一个权限。这是两个权限。
短信的读取是一个权限,短信的发送是操作短信的另一个权限。

layout布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_contact"
        android:text="获取通讯录的读写权限"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn_sms"
        android:text="获取短信的查看发送权限"/>
</LinearLayout>

获取通讯录的读写权限按钮的id是:btn_contact
获取短信的查看发送权限按钮的id是:btn_sms

在这里插入图片描述

回调函数onRequestPermissionsResult

该回调函数会在用户点击完动态获取权限的弹窗后执行。当弹出动态获取权限的窗口后,用户在该窗口进行选择“允许”或“不允许”,当选择完后,即可在该回调函数中进行相应的判断,判断用户是否允许了权限。

该函数在MainActivity类中

//点击申请权限弹框后的回调函数
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

权限判断工具类

public class PermissionUtil {

    //检查某个功能的多个权限,返回true表示已完全启用权限,返回false表示未完全启用权限
    //比如通讯录这个功能,需要获取它有的多个权限[读权限,写权限]
    //act:当前的Activity 
    //permissions:某个功能的权限集合,如通讯录的[读,写]
    //requestCode:标识一下“某个功能”
    public static boolean checkPermission(Activity act, String[] permissions, int requestCode){

        //判断android的版本
        //Build.VERSION.SDK_INT:当前android的版本
        //Build.VERSION_CODES.M:android6.0
        if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){//安卓版本在6.0及以后才需要判断  M就是6.0
           
           //check的含义:权限是否开启
           //这里给了默认值PackageManager.PERMISSION_GRANTED,意思是开启权限
            int check = PackageManager.PERMISSION_GRANTED;//默认授权的值
            for (String permission:permissions){
                //返回结果为是否授权
                check = ContextCompat.checkSelfPermission(act, permission);
                //如果没有授权,则退出
                if (check!=PackageManager.PERMISSION_GRANTED){
                    break;
                }
            }
            //未开启该权限,则请求系统弹窗,好让用户选择是否立即开启权限
            if (check!=PackageManager.PERMISSION_GRANTED){
                //弹窗,用户操作
                ActivityCompat.requestPermissions(act,permissions,requestCode);
                return false;
            }

        }

        return true;
    }

    //grantResults:是用户点“授权”完弹窗后的授权结果数组
    //检查权限结果数组,返回true表示都已经获得授权。返回false表示至少有一个未获得授权
    public static boolean checkGrant(int[] grantResults) {

        if (grantResults!=null){

            //遍历权限结果数组中的每条选择结果
            for (int grant:grantResults){
                //未获得授权
                if (grant!=PackageManager.PERMISSION_GRANTED){
                    return false;
                }

            }
            return true;
        }

        return false;
    }
}

清单文件

声明权限权限(必须声明)

<!--    声明读写通讯录权限-->
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!--声明读发短信权限-->
    <uses-permission android:name="android.permission.READ_SMS"/>
    <uses-permission android:name="android.permission.SEND_SMS"/>

在这里插入图片描述

方式一:懒汉式

上面说过,懒汉式,是在app操作到特定功能时从获取相应权限,在这里的“特定功能”就是在点击按钮时,动态获取权限。

定义权限数组

//通信录的读写权限
    private static final String[] PERMISSIONS_CONTACTS=new String[]{
            Manifest.permission.READ_CONTACTS,//读通讯录
            Manifest.permission.WRITE_CONTACTS//写通讯录
    };

    //短信的发送、读取权限
    private static final String[] PERMISSIONS_SMS=new String[]{
            Manifest.permission.SEND_SMS,//发送短信
            Manifest.permission.READ_SMS//读取短信
    };

标识码

//标识通讯录
    private static final int REQUEST_CODE_CONTACTS=1;
    //标识短信
    private static final int REQUEST_CODE_SMS=2;

点击事件监听
实现View.OnClickListener,并实现onClick方法

@Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_contact:
                PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_CONTACTS);
                break;
            case R.id.btn_sms:
                PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_SMS);
                break;
        }
    }

我们可以看到,如果没有授权就会执行到工具类PermissionUtil中的如下语句:

ActivityCompat.requestPermissions(act,permissions,requestCode);

它会出现弹窗,给用户选择是否获取所有权限
在这里插入图片描述
用户选择完后就会回调Activity中的,所以我们可以在该函数中进行是否授权的判断

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

MainActivity完整代码

package com.example.demo8;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.Manifest;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;

import com.example.demo8.util.PermissionUtil;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    //通信录的读写权限
    private static final String[] PERMISSIONS_CONTACTS=new String[]{
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_CONTACTS
    };

    //短信的发送、读取权限
    private static final String[] PERMISSIONS_SMS=new String[]{
            Manifest.permission.SEND_SMS,
            Manifest.permission.READ_SMS
    };

    //标识通讯录
    private static final int REQUEST_CODE_CONTACTS=1;
    //标识短信
    private static final int REQUEST_CODE_SMS=2;

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

        //设置监听事件
        findViewById(R.id.btn_contact).setOnClickListener(this);
        findViewById(R.id.btn_sms).setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_contact:
                //上下文、权限数组、标识
                PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_CONTACTS);
                break;
            case R.id.btn_sms:
                PermissionUtil.checkPermission(this,PERMISSIONS_SMS,REQUEST_CODE_SMS);
                break;
        }
    }


    //点击申请权限弹框后的回调函数
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode){
            case REQUEST_CODE_CONTACTS:
                if (PermissionUtil.checkGrant(grantResults)){
                    Toast.makeText(this, "通讯录权限获取成功", Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(this, "获取通讯录读写权限获取失败", Toast.LENGTH_SHORT).show();
                }
                break;
            case REQUEST_CODE_SMS:
                if (PermissionUtil.checkGrant(grantResults)){
                    Toast.makeText(this, "收发短信权限获取成功", Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(this, "收发短信权限获取失败", Toast.LENGTH_SHORT).show();
                }
                break;
        }

    }
}

方式二:饿汉式

饿汉式,是在“onCreate”的时候就进行权限的申请,一次性到位。

我们将所有需要申请的权限放到一个数组中

//将权限放到一个数组中
    private static final String[] PERMISSIONS=new String[]{
            //通信录的读写权限
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_CONTACTS,

            //短信的发送、读取权限
            Manifest.permission.SEND_SMS,
            Manifest.permission.READ_SMS
    };

在oncreate中进行权限的申请
在这里插入图片描述
其余原理与懒汉式相同,只是申请权限的时间不同而已。

通讯录
在这里插入图片描述
短信
在这里插入图片描述
MainActivity代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener{


    //将权限放到一个数组中
    private static final String[] PERMISSIONS=new String[]{
            //通信录的读写权限
            Manifest.permission.READ_CONTACTS,
            Manifest.permission.WRITE_CONTACTS,

            //短信的发送、读取权限
            Manifest.permission.SEND_SMS,
            Manifest.permission.READ_SMS
    };

    private static final int REQUEST_CODE=1;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /初始获取权限
        PermissionUtil.checkPermission(this,PERMISSIONS,REQUEST_CODE);

        //设置监听事件
        findViewById(R.id.btn_contact).setOnClickListener(this);
        findViewById(R.id.btn_sms).setOnClickListener(this);
    }
//饿汉式这里无用
    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_contact:
                break;
            case R.id.btn_sms:
                break;
        }
    }


    //点击申请权限弹框后的回调函数
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode){
            case REQUEST_CODE:
                if (PermissionUtil.checkGrant(grantResults)){
                    Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show();
                }else{
                    Toast.makeText(this, "权限获取失败", Toast.LENGTH_SHORT).show();
                }
                break;
        }

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/382855.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

美颜sdk动态贴纸的实现流程

随着移动互联网时代的到来&#xff0c;各式各样的 APP层出不穷&#xff0c;从最初的微信、 QQ到如今的抖音、快手等等&#xff0c;再到如今的微博、小红书等等&#xff0c;各式各样的 APP不断涌现。从最开始简单的图片展示到视频聊天&#xff0c;再到现如今丰富多样的各种动态贴…

rip题解

1.查看文件保护机制 使用的是新版本的checksec 2.拖入IDA分析 查壳 是一个64文件&#xff0c;拖入64位IDA 这个文件就是我们要攻击的服务器中的一个进程的代码&#xff0c;进程就是一个正在运行的程序 分析敏感函数 打开字符串窗口 跟进&#xff0c;光标点在command&#x…

Linux: ARM GIC只中断CPU 0问题分析

文章目录1. 前言2. 分析背景3. 问题4. 分析4.1 ARM GIC 中断芯片简介4.1.1 中断类型和分布4.1.2 拓扑结构4.2 问题根因4.2.1 设置GIC SPI 中断CPU亲和性4.2.2 GIC初始化&#xff1a;缺省的CPU亲和性4.2.2.1 boot CPU亲和性初始化流程4.2.2.1 其它非 boot CPU亲和性初始化流程5.…

【微信小程序】-- 全局配置 -- window - 下拉刷新 上拉触底(十六)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

模型实战(6)之Alex实现图像分类:模型原理+训练+预测(详细教程!)

Alex实现图像分类:模型原理+训练+预测 图像分类或者检索任务在浏览器中的搜索操作、爬虫搜图中应用较广,本文主要通过Alex模型实现猫狗分类,并且将可以复用的开源模型在文章中给出!!!数据集可以由此下载:Data本文将从以下内容做出讲述: 1.模型简介及环境搭建2.数据集准…

微纳制造期末复习

章节分为六个模块&#xff1a; 1. 微纳制造中的材料 2.光刻技术 3.微纳制造中使用的技术 4.刻蚀 5.沉积 7.微纳刻蚀 根据导电性区分材料&#xff1a;导体&#xff0c;半导体&#xff0c;绝缘体 晶体&#xff1a;长程有序 多晶&#xff1a;短程有序 非晶&#xff1a;无序…

八 SpringMVC【拦截器】登录验证

目录&#x1f6a9;一 SpringMVC拦截器✅ 1.配置文件✅2.登录验证代码&#xff08;HandlerInterceptor&#xff09;✅3.继承HandlerInterceptorAdapter&#xff08;不建议使用&#xff09;✅4.登录页面jsp✅5.主页面&#xff08;操作页面&#xff09;✅6.crud用户在访问页面时 只…

【算法】PatchMatch立体匹配算法_原理解析

目录 前言 原理解析 1.倾斜支持窗口&#xff08;Slanted Support Windows&#xff09; 什么是视差平面&#xff1f; 为什么视差和像素坐标点之间的关系可以解释为平面方程&#xff1f; 视差平面的通用参数方程和点加法向量方程 什么是倾斜支持窗口&#xff1f; 2.基于倾…

宏基因组鉴定病毒流程中需要的生物信息工具

谷禾健康 许多流行病的爆发都是病毒引起的&#xff0c;面对新的传染性基因组出现的最佳策略是及时识别&#xff0c;以便于在感染开始时立即实施相应措施。 目前可用的诊断测试仅限于检测新的病理因子。适用于同时检测存在的任何病原体的高通量方法可能比使用基于当前方法的大量…

Mel Spectrogram

参考链接&#xff1a; Short-time Fourier transform - MATLAB stft- MathWorks 中国 https://medium.com/analytics-vidhya/understanding-the-mel-spectrogram-fca2afa2ce53 a spectrogram as a bunch of FFTs stacked on top of each other. 给出hop length后&#xff0…

TMP耗时较高的优化问题

1&#xff09;TMP耗时较高的优化问题 ​2&#xff09;Unity重载Object后&#xff0c;如何判定物体是否为空 3&#xff09;SRP Batch在添加unity_SpecCube后的问题 4&#xff09;堆内存会持续上升&#xff0c;如何用UWA报告来分析 这是第326篇UWA技术知识分享的推送&#xff0c;…

大话数据结构-栈

1 概述 栈&#xff08;Stack&#xff09;是限定仅在表尾进行插入和删除操作的线性表。 允许插入和删除的一端称为栈顶&#xff08;top&#xff09;&#xff0c;另一端称为栈底&#xff08;bottom&#xff09;&#xff0c;不含任何数据元素的栈称为空栈&#xff0c;栈又称为后进…

界面控件DevExpress WinForm——轻松构建类Visual Studio UI(三)

DevExpress WinForm拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜任…

MyBatisPlus Study Notes

文章目录1 MyBatisPlus概述1.1 MyBatis介绍1.2 MyBatisPlus特性2 标准数据层开发2.1 MyBatisPlus的CRUD操作API2.2 分页功能接口实现2.2.1 config&#xff08;配置层&#xff09;拦截器实现2.2.2 Dao(Mapper)数据访问层&#xff08;CRUD&#xff09;操作2.2.3 Junit单元测试进行…

新版本GPU加速的tensorflow库的配置方法

本文介绍在Anaconda环境中&#xff0c;配置可以用GPU运行的Python新版tensorflow库的方法。 在上一篇文章Anaconda配置Python新版本tensorflow库&#xff08;CPU、GPU通用&#xff09;的方法&#xff08;https://blog.csdn.net/zhebushibiaoshifu/article/details/129285815&am…

【分布式】10张图带你彻底搞懂限流、熔断、服务降级

文章目录1 限流1.1 限流指标1.1.1 TPS1.1.2 HPS1.1.3 QPS1.2 限流方法1.2.1 流量计数器1.2.2 滑动时间窗口1.2.3 漏桶算法1.2.4 令牌桶算法1.2.5 分布式限流1.2.6 hystrix限流1.2.6.1 信号量限流1.2.6.2 线程池限流2 熔断2.1 断路器的状态2.2 需要考虑的问题2.3 使用场景3 服务…

游戏开发是个“坑”,而且是个“天坑”

本文首发于CSDN公众号 作者 | 开发游戏的老王 责编 | 梦依丹 出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09; 各位游戏开发者大家好&#xff0c;我是开发游戏的老王&#xff0c;一名游戏开发者同时也是一名高校游戏方向的主讲教师&#xff0c;从事游戏开发及相关教…

HTTP缓存从入门到踹门

1 与缓存相关的字段Expires&#xff1a;缓存的绝对过期时间Cache-Control&#xff1a;缓存的相对过期时间Last-Modified&#xff1a;缓存上一次修改的时间&#xff08;服务端保存&#xff09;If-Modified-Since&#xff1a;缓存上一次修改的时间&#xff08;客户端保存&#xf…

第十一届蓝桥杯省赛——2解密

题目&#xff1a;【问题描述】小明设计了一种文章加密的方法&#xff1a;对于每个字母 c&#xff0c;将它变成某个另外的字符 Tc。下表给出了字符变换的规则&#xff1a;字母cTc字母cTc字母cTc字母cTcaynlAYNLbxogBXOGcmpoCMPOddquDDQUearfEARFfcssFCSSgitzGITZhkupHKUPinvwINV…

【ArcGIS Pro二次开发】(11):面要素的一键拓扑

在工作中&#xff0c;经常需要对要素进行拓扑检查。 在ArcGIS Pro中正常的工作流程是在数据库中【新建要素数据集——新建拓扑——将要素加入拓扑——添加规则——验证】&#xff0c;工作流程不算短&#xff0c;操作起来比较繁琐。 下面以一个例子演示如何在ArcGIS Pro SDK二次…