Android权限动态申请(包括悬浮窗)

news2024/11/18 1:50:47

目录

效果图

一、环境配置

二、新建工具类

 三、开始使用

备注(一):用户手动设置权限

手动设置效果图

备注(二):在Fragment中如何调用动态权限申请

备注(三):悬浮窗权限处理

1、配置环境

 2、核心代码

 3、在需要使用的地方调用上面的函数

悬浮窗申请效果图


效果图

一、环境配置

AndroidManifest.xml中先配置需要的权限,这里以【读写通讯录】权限为例: 

<uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- 联系人权限-读 -->
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> <!-- 联系人权限-写 -->

二、新建工具类

新建一个工具类PermissionUtil.class,用于循环【验证权限】、【申请权限】及【申请权限后用户的选择结果】的操作处理。

/**
 * 权限工具类
 */
public class PermissionUtil {

    /**
     * 判断是否权限都已授权,存在未授权则进行申请授权
     * @param activity
     * @param permissions 权限列表
     * @param requestCode
     * @return
     */
    public static boolean checkPermission (Activity activity, String[] permissions, int requestCode ) {

        // 默认已经授权
        int check = PackageManager.PERMISSION_GRANTED;

        // 判断安卓版本是否是大于6.0(6.0及以上才需要申请权限)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            // 循环处理
            for (String permission : permissions) {
                // 验证单个权限是否授权-【核心】
                check = ContextCompat.checkSelfPermission(activity, permission);
                // 判断发现存在某一个未授权
                if (check != PackageManager.PERMISSION_GRANTED) {
                    break;
                }
            }
        }

        // 存在某一个未授权,重新进行申请权限
        if (check != PackageManager.PERMISSION_GRANTED) {

            // 执行权限列表的申请-【核心】
            ActivityCompat.requestPermissions(activity, permissions, requestCode);
            return false;
        }

        return true;
    }


    /**
     * 判断权限集合是否授权结果里是否存在未授权的情况,如果有返回false,否则反之
     * @param grantResults
     * @return
     */
    public static boolean checkGrant (int[] grantResults) {

        // 判断是否存在结果集合,没有直接返回false
        if (grantResults != null) {
            // 循环判断
            for (int grant : grantResults) {
                // 判断是否有未授权
                if (grant != PackageManager.PERMISSION_GRANTED) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
}

 三、开始使用

在需要使用的activity中,添加以下代码,通过前面的工具类PermissionUtil中的checkPermission方法进行【验证权限】和【申请权限】,然后通过onRequestPermissionsResult监听【申请权限后用户的选择结果】:

    private static final int REQUEST_CODE = 1; // 申请权限状态标识

    private static final String[] PERMISSIONS_CONTACTS = new String[] {
        // 申请权限集合
        Manifest.permission.READ_CONTACTS,
        Manifest.permission.WRITE_CONTACTS
    };

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

        // 判断是否有获取对应权限,没有则进行申请
        PermissionUtil.checkPermission(getActivity(), PERMISSIONS_CONTACTS, REQUEST_CODE);
    }

    /**
     * 判断申请权限用户是否同意
     * @param requestCode The request code passed in
     * @param permissions The requested permissions. Never null.
     * @param grantResults The grant results for the corresponding permissions
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_CODE) {
            if (PermissionUtil.checkGrant(grantResults)) {
                // 用户授予了权限,执行相应操作
                Log.d(TAG, "用户授予了权限");

            } else {
                // 用户拒绝了权限
                Log.e(TAG, "用户拒绝了权限");

            }
        }
    }

备注(一):用户手动设置权限

因为用户一旦拒绝2次权限申请,就不会再提示该权限的申请,就需要一个一个跳转该app的系统设置-权限页面,让用户手动设置的方法,如下所示:

    // 跳转设置-权限
    private void jumpToSetting () {
        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        intent.setData(Uri.fromParts("package", getPackageName(), null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
手动设置效果图

备注(二):在Fragment中如何调用动态权限申请

 代码基本一致,只是要在父activity中加上这一段代码:

    // 在Activity中遍历所有的Fragment,并调用它们的onRequestPermissionsResult方法
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        for (Fragment fragment : getSupportFragmentManager().getFragments()) {
            if (fragment != null) {
                fragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    }

备注(三):悬浮窗权限处理

悬浮窗权限比较特殊,无法弹出给用户选择,需要跳转到系统设置,让用户自己手动开启

1、配置环境
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><!-- 悬浮窗权限 -->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" /><!-- 悬浮窗权限 -->
 2、核心代码

直接复制粘贴拿去用就好:

    // 判断是否有悬浮窗权限
    public boolean isOverlayPermission(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return Settings.canDrawOverlays(context);
        } else {
            try {
                Class clazz = Settings.class;
                Method method = clazz.getDeclaredMethod("canDrawOverlays", Context.class);
                return (Boolean) method.invoke(null, context);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    // 跳转系统设置-悬浮窗页面
    public void jumpToPermission() {
        Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getContext().getPackageName()));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }
 3、在需要使用的地方调用上面的函数
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        // 判断是否有获取悬浮窗,有的话才执行startService
        if (isOverlayPermission(getContext())) {
            // 悬浮窗权限已被授予,可以显示悬浮窗
            Log.d(TAG, "悬浮窗权限已被授予");
           
        } else {
            // 悬浮窗权限未被授予
            Log.e(TAG, "悬浮窗权限未被授予");

            // 跳转系统设置去手动开启
            jumpToPermission();
        }
    }
悬浮窗申请效果图

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

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

相关文章

SDL2 显示文字

1.简介 SDL本身没有显示文字功能&#xff0c;它需要用扩展库SDL_ttf来显示文字。ttf是True Type Font的缩写&#xff0c;ttf是Windows下的缺省字体&#xff0c;它有美观&#xff0c;放大缩小不变形的优点&#xff0c;因此广泛应用很多场合。 使用ttf库的第一件事要从Windows的…

【leetcode】8.字符串转换整数

题目 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 myAtoi(string s) 的算法如下&#xff1a; 读入字符串并丢弃无用的前导空格 检查下一个字符&#xff08;假设还未…

【文末送书】深入浅出嵌入式虚拟机原理

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于回溯搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

二维码智慧门牌管理系统升级解决方案:数据可视化助力运营精准决策

文章目录 前言一、升级版二维码智慧门牌管理系统的特点二、数据可视化助力运营精准决策 前言 随着科技的不断进步&#xff0c;传统的门牌管理系统已经无法满足现代社会的需求。为了提高管理效率&#xff0c;减少人力成本&#xff0c;我们引入了升级版的二维码智慧门牌管理系统…

[PyTorch][chapter 62][强化学习-基本概念]

前言&#xff1a; 目录&#xff1a; 强化学习概念 马尔科夫决策 Bellman 方程 格子世界例子 一 强化学习 强化学习 必须在尝试之后&#xff0c;才能发现哪些行为会导致奖励的最大化。 当前的行为可能不仅仅会影响即时奖赏&#xff0c;还有影响下一步奖赏和所有奖赏 强…

如何应对招聘中的职业性格测评?

很多同学听说要做性格测试&#xff0c;第一反应是如何让自己的性格让HR看起来更好....没办法为了顺利入职&#xff0c;咱不能老实作答&#xff0c;因为性格测评搞不好是真刷人的&#xff0c;刷人的&#xff08;无视你的专业能力和笔试成绩&#xff09;..... 可是....很多性格测…

eNSP-打开华为USG6000V1防火墙web管理页面方法

一、本地打开防火墙web管理页面 1.先在ensp中启动USG6000V1防火墙&#xff0c;启动后&#xff0c;需要输入原始username和password&#xff08;username&#xff1a;admin&#xff0c;password&#xff1a;Admin123&#xff09;&#xff0c;并修改原始密码后&#xff0c;才能配…

SQL学习(CTFhub)整数型注入,字符型注入,报错注入 -----手工注入+ sqlmap注入

目录 整数型注入 手工注入 为什么要将1设置为-1呢&#xff1f; sqlmap注入 sqlmap注入步骤&#xff1a; 字符型注入 手工注入 sqlmap注入 报错注入 手工注入 sqlmap注入 整数型注入 手工注入 先输入1 接着尝试2&#xff0c;3&#xff0c;2有回显&#xff0c;而3没有回显…

做一个springboot用户信息模块

目录 用户信息部分 1、获取用户详细信息 前言 代码分析 代码实现 测试 2、更新用户信息 前言 代码实现 测试 3、更新用户头像 前言 代码实现 测试 4、更新用户密码 前言 代码实现 测试 用户信息部分 1、获取用户详细信息 前言 承接上一篇博客登录注册功能…

快速批量去除文件夹名称中多余重复文字!一键轻松优化文件夹命名!

您是否曾经因为文件夹名称中多余重复文字而烦恼&#xff1f;是否因为文件夹重命名而浪费大量时间&#xff1f;现在&#xff0c;我们为您推荐一款全新的文件夹批量改名工具——快速批量去除文件夹名称中多余重复文字&#xff0c;轻松实现文件夹改名优化&#xff0c;让您的整理效…

Leetcode_2:两数相加

题目描述&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff…

106.am40刷机(linux)折腾记2-前期的准备工作2-软件使用

最终的目标是刷入firefly的3399的镜像&#xff0c;同时更新内核到linux5.10版本&#xff08;4.4的内核应该是相同的方法&#xff0c;我目前没有去折腾&#xff0c;暂时不用了&#xff09;。 1. 平台&#xff1a; rk3399 am40 4g32g 2. 内核&#xff1a;暂无 3. 交叉编译工…

数据结构----顺序栈的操作

1.顺序栈的存储结构 typedef int SElemType; typedef int Status; typedef struct{SElemType *top,*base;//定义栈顶和栈底指针int stacksize;//定义栈的容量 }SqStack; 2.初始化栈 Status InitStack(SqStack &S){//初始化一个空栈S.basenew SElemType[MAXSIZE];//为顺序…

macOS文本编辑器 BBEdit 最新 for mac

BBEdit是一款功能强大的文本编辑器&#xff0c;适用于Mac操作系统。它由Bare Bones Software开发&#xff0c;旨在为开发者和写作人员提供专业级的文本编辑工具。 以下是BBEdit的一些主要特点和功能&#xff1a; 多语言支持&#xff1a;BBEdit支持多种编程语言和标记语言&…

jstack java堆栈跟踪工具

jstack java堆栈跟踪工具 1、jstack介绍 jstack&#xff08;stack trace for java&#xff09;是java虚拟机自带的一种堆栈跟踪工具。 jstack主要用于生成java虚拟机当前时刻的线程快照&#xff0c;线程快照是当前java虚拟机内每一条线程正在执行的方法 堆栈的集合&#xf…

信息安全工程师软考知识点

文章目录 知识点总结2023软考总结选择题问答题 知识点总结 军用不对外公开的信息系统安全等级至少应该>三级 数据中心的耐火等级不应低于二级 政府网站的信息安全等级原则上不应低于二级第一代交换机以集线器为代表&#xff0c;工作在OSI物理层 第二代交换机以太网交换机&a…

关于论文图表目录和交叉引用的使用小结

目录 1 题注用法 2 交叉引用 最近在写论文&#xff0c;遇到不少Word使用的问题(错误&#xff01;文档中没有指定样式的文字。) 网上其实也有很多解决方案但我当时还是折腾了几个小时才整出来图目录&#xff0c;以下是针对我目前使用的感觉简明很多的方法。 1 题注用法 1) 假…

Selenium+JQuery定位方法及应用

SeleniumJQuery定位方法及应用 1 JQuery定位说明1.1 JQuery定位方法1.2 JQuery最常用的三个操作1.3 JQuery一个示例1.3.1 用户名输入框1.3.2 密码输入框1.3.3 登陆按钮1.3.4 完整代码 2 JQuery选择器2.1 常用选择器列表2.2 思考 1、关于Selenium提供了很多元素定位方法&#xf…

解决计算中msvcp120.dll丢失问题,总结5个有效的方法

msvcp120.dll是Microsoft Visual C 2013 Redistributable中的一个动态链接库文件&#xff0c;它提供了许多重要的函数和类&#xff0c;用于支持各种应用程序的正常运行。当这个文件丢失或损坏时&#xff0c;可能会导致一些应用程序无法启动或运行错误。 msvcp120.dll的属性 文件…