Android 运行时权限

Android 6.0 及以后,如果你的应用需要用到一些危险权限,那么这些权限必须手动申请
具体危险权限有哪些,可以通过下面这篇文章自行查询到:
使用 adb 命令列出设备所有危险权限

例如,读写文件就涉及到两个危险权限:
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE

步骤1:声明权限

首先,你必须在 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"><!-- 读写文件 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /></manifest>

对于危险权限来说,声明了并不意味着你就拥有这些权限,你还必须手动申请。

步骤2:查询是否有权限

在读写文件之前,你必须检查你是否拥有读写文件的权限。
通过 ContextCompatcheckSelfPermission 函数就可以检查是否拥有指定权限。

例如:

ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)

第一个参数是 Context
第二个参数是需要检查的权限名称。
该函数返回一个 Int 类型的值,其结果只有两种:PackageManager.PERMISSION_GRANTEDPackageManager.PERMISSION_DENIED

  • PERMISSION_GRANTED:有此权限
  • PERMISSION_DENIED:无此权限

综上所述,我们可以通过判断来处理相应的逻辑:

if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
) {Log.d(TAG, "有权限")
} else {Log.d(TAG, "无权限")
}

步骤3:申请权限

对于没有的权限,你就必须手动去申请。
通过 ActivityCompatrequestPermissions 函数就可以手动申请权限。

例如:

ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE)

第一个参数是 Activity;
第二个参数是将要申请的权限放在一个数组里,可以同时申请多个权限;
第三个参数是申请码,权限申请是一个异步操作,申请结果会通过onRequestPermissionsResult回调告诉你,通过比较requestCode来定位你申请的结果

结合 ContextCompat.checkSelfPermission 一起使用:

if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
) {Log.d(TAG, "有权限")
} else {Log.d(TAG, "无权限")ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),PERMISSION_REQUEST_CODE)
}

步骤4:申请结果

权限申请是一个异步操作,申请结果以回调的方式告知你。
通过 onRequestPermissionsResult 回调函数可以得到申请结果。

例如:

override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray
) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {PERMISSION_REQUEST_CODE -> {if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {Log.d(TAG, "权限申请成功")} else {Log.d(TAG, "权限申请失败")}}}
}

综合案例

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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.appcompat.widget.AppCompatButtonandroid:id="@+id/main_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="申请权限"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>

MainActivity

class MainActivity : AppCompatActivity() {private val TAG = "MainActivity"private val PERMISSION_REQUEST_CODE = 1override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val button: AppCompatButton = findViewById(R.id.main_btn)button.setOnClickListener {requestPermission()}}private fun requestPermission() {if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {Log.d(TAG, "有权限")work()} else {Log.d(TAG, "无权限")ActivityCompat.requestPermissions(this,arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),PERMISSION_REQUEST_CODE)}}override fun onRequestPermissionsResult(requestCode: Int,permissions: Array<out String>,grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)when (requestCode) {PERMISSION_REQUEST_CODE -> {if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {Log.d(TAG, "权限申请成功")work()} else {Log.d(TAG, "权限申请失败")}}}}private fun work() {Log.d(TAG, "工作")}
}

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

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

相关文章

Unity 中获取调用者方法名

介绍 在 Unity 开发中&#xff0c;有时需要在代码中获取当前方法的调用者方法名&#xff0c;以便进行日志记录、调试等操作。本教程将详细介绍如何使用 C# 中的 StackTrace 类来实现这一功能&#xff0c;并将其封装成一个便捷的工具类&#xff0c;以方便在项目中的任何地方…

ES的安装以及配置+ik分词

环境&#xff1a;windows10、ES&#xff08;8.13.3&#xff09;、Kibana&#xff08;8.13.3&#xff09;、Logstash&#xff08;8.13.3&#xff09;、ik&#xff08;8.13.3&#xff09; 1.下载安装ES Download Elasticsearch | ElasticDownload Elasticsearch or the complet…

AI预测体彩排3采取888=3策略+和值012路一缩定乾坤测试5月26日预测第2弹

今天继续基于8883的大底进行测试&#xff0c;昨天的预测已成功命中&#xff01;今天继续测试&#xff0c;按照排三前面的规律&#xff0c;感觉要出对子了&#xff0c;所以本次预测不再杀对子&#xff0c;将采用杀一个和尾来代替。好了&#xff0c;直接上结果吧~ 首先&#xff0…

mongoengine,一个非常实用的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超酷的 Python 库 - mongoengine。 Github地址&#xff1a;https://github.com/MongoEngine/mongoengine 在现代应用程序开发中&#xff0c;NoSQL数据库因其灵活性和高性能而广受欢迎。MongoD…

软件需求规范说明模板

每个软件开发组织都会为自己的项目选用一个或多个标准的软件需求规范说明模板。有许多软件需求规范说明模板可以使用(例如ISO/IEC/IEEE2011;Robertson and Robertson2013)。如果你的组织要处理各种类型或规模的项目&#xff0c;例如新的大型系统开发或是对现有系统进行微调&…

concurrency 并行编程

Goroutine go语言的魅力所在&#xff0c;高并发。 线程是操作系统调度的一种执行路径&#xff0c;用于在处理器执行我们在函数中编写的代码。一个进程从一个线程开始&#xff0c;即主线程&#xff0c;当该线程终止时&#xff0c;进程终止。这是因为主线程是应用程序的原点。然后…

红黑树封装map和set

红黑树源代码 我们将由下列的KV模型红黑树来模拟封装STL库中的map和set 注意&#xff1a;为了实现封装map和set&#xff0c;我们需要对下列源码进行优化。 #pragma once #include<iostream> using namespace std; //枚举类型的颜色分类 enum Colour {RED,BLACK };//定…

【Python爬虫】图片验证码的处理

什么是图片验证码&#xff1f; 验证码&#xff08;CAPTCHA&#xff09;是&#xff02;Completely Automated Public Turing test to tell Computers and HumansApart”&#xff08;全自动区分计算机和人类的图灵测试&#xff09;的缩写&#xff0c;是一种区分用户是计算机还是人…

Markdown魔法手册:解锁高效写作的新技能

边使用边更新0.0... 文章目录 一、如何在Markdown中插入表情&#xff1f;二、文字样式设置1.文本颜色设置2.文本字号设置3.文本字体设置4. 实战演练5.黄色高亮 一、如何在Markdown中插入表情&#xff1f; 在Markdown中插入表情&#xff08;emoji&#xff09;的方法取决于你使用…

如何提升百度小程序的收录?百度小程序如何做优化?

​ 如何通过百度小程序获得更多的自然流量&#xff1f;这是做百度小程序肯定要考虑的问题&#xff0c;做百度小程序的目的就是想借助百度生态&#xff0c;做相应的关键词给自己的小程序引流&#xff0c;如何把流量给做起来呢&#xff0c;接下来我从不同的方面给大家进行分析讲解…

最新ChatGpt Desktop for Mac 安装使用教程

1. 下载地址 请点击链接下载 ChatGPT Desktop for MacOS 2. 使用要求 MacOS 版本 14需要时M1芯片的&#xff0c;如果你是因特尔的暂时还还不行 就算下载了也会出现下面的异常 3. 获取权限资格 目前 ChatGPT MacOS Desktop还不是全量开放的, 如果你没有收到通知说明你还没…

在 Dockerfile 中遇到了连接到 pypi.org 超时的问题

看起来你在 Dockerfile 中遇到了连接到 pypi.org 超时的问题。这可能是由于网络连接问题导致的。你可以尝试以下方法解决这个问题&#xff1a; 1. 更换镜像源&#xff1a; 有时候 pypi.org 的访问会受到地理位置或网络环境的影响&#xff0c;你可以考虑使用国内的镜像源来代…

Oracle的ROWID解析

目录 一、ROWID基础概念二、ROWID的类型三、ROWID的用途四、注意事项五、管理与监控 Oracle的ROWID是一个非常核心的概念&#xff0c;它代表了一行数据在数据库中的物理位置标识。 一、ROWID基础概念 唯一性与不变性&#xff1a;ROWID是每行数据的唯一标识符&#xff0c;它在行…

【Spark】调整hive表在HDFS存的每个文件的大小

配置参数&#xff1a; spark.hadoop.hive.exec.orc.default.stripe.size78643200 spark.hadoop.orc.stripe.size78643200 spark.hadoopRDD.targetBytesInPartition78643200 spark.hadoop.hive.exec.dynamic.partition.modenonstrict spark.sql.sources.partitionOverwriteMode…

ipa 覆盖算法测试

相关文章 ipa 功能包测试 ipa 分区算法 ipa 分区算法总结&#xff0c;部分算法图解 ipa 覆盖算法分析&#xff08;一&#xff09; ipa 覆盖算法分析&#xff08;二&#xff09; 测试 网上找的地图&#xff1a; fig.1 测试地图 opencv fig.2 opencv 显示的覆盖路径 rviz fi…

6.定时器分时复用测量占空比

1.CUBEMAX配置 测量PA6&#xff0c;PA7输出的占空比&#xff0c;只需要把主要的配置&#xff0c;配置为A6口就行&#xff0c;A7口黄色表示配置不正确&#xff0c;不用管。 2.软件代码 TIME.c中找到TIM3的初始化&#xff0c;在后面初始化A7口 void MX_TIM3_Init_PA7(void) {/*…

创新实训2024.05.25日志:Web应用技术选型

我们的web应用使用python web的fastapi框架&#xff0c;通过uvicorn开启web服务。 1. refs 官网文档&#xff1a;FastAPI (tiangolo.com) github&#xff1a;https://github.com/tiangolo/fastapi 2. 环境配置 python:3.11 uvicorn:0.29.0 pip install "uvicorn[stan…

老外卖27刀每月的教程已经更新

用了两天半的时间&#xff0c;边学习&#xff0c;边整理了一份老外的视频教程&#xff0c;涉及Facebook&#xff0c;YouTube&#xff0c;tiktok等大的流量平台&#xff0c;有案例&#xff0c;有分析&#xff0c;有如何做。 这个教程是老外讲的&#xff0c;没有什么玄乎的塑造价…

理解矩阵内积与矩阵乘法的区别及其应用

文章目录 矩阵内积&#xff08;逐元素乘积&#xff09;矩阵内积的用途矩阵乘法&#xff08;矩阵积&#xff09;矩阵乘法的用途区别总结结论 在数据科学、机器学习、计算机图形学和图像处理等领域&#xff0c;矩阵运算是非常基础且重要的操作。然而&#xff0c;矩阵内积和矩阵乘…