Android 在程序运行时申请权限——以自动拨打电话为例

news2024/10/2 3:32:25

Android 6.0及以上系统在使用危险权限时必须进行运行时权限处理。
main_activity.xml

<?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"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/makeCall"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Make Call" />
</LinearLayout>

Manifest.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.CALL_PHONE" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        ...
    </application>

</manifest>

MainActivity

import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val makeCall: Button = findViewById(R.id.makeCall)
        makeCall.setOnClickListener {
            // 先判断用户是不是已经授权过了
            if(ContextCompat.checkSelfPermission(this, android.Manifest.permission.CALL_PHONE) !=
                // 未授权则向用户申请权限
                PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(this, arrayOf(android.Manifest.permission.CALL_PHONE), 1)
            }else{
                // 已经授权则直接拨打电话
                call()
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when(requestCode){
            1 -> {
                if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    call()
                }else{
                    Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun call(){
        try {
            val intent = Intent(Intent.ACTION_CALL)
            intent.data = Uri.parse("tel:10086")
            startActivity(intent)
        }catch (e: SecurityException){
            e.printStackTrace()
        }
    }
}

第一步要先判断用户是不是已经给过我们授权了,借助的是ContextCompat.checkSelfPermission()方法。checkSelfPermission()方法接收两个参数:

  • 第一个参数是Context;
  • 第二个参数是具体的权限名,比如打电话的权限名就是Manifest.permission.CALL_PHONE。

然后我们使用方法的返回值和PackageManager.PERMISSION_GRANTED做比较,相等就说明用户已经授权,不等就表示用户没有授权。

如果已经授权的话就简单了,直接执行拨打电话的逻辑操作就可以了。如果没有授权的话,则需要调用ActivityCompat.requestPermissions()方法向用户申请授权。requestPermissions()方法接收3个参数:

  • 第一个参数要求是Activity的实例;
  • 第二个参数是一个String数组,我们把要申请的权限名放在数组中即可;
  • 第三个参数是请求码,只要是唯一值就可以了,这里传入了1。

调用完requestPermissions()方法之后,系统会弹出一个权限申请的对话框,用户可以选择同意或拒绝我们的权限申请。不论是哪种结果,最终都会回调到onRequestPermissionsResult()方法中,而授权的结果则会封装在grantResults参数当中。这里我们只需要判断一下最后的授权结果:如果用户同意的话,就调用call()方法拨打电话;如果用户拒绝的话,我们只能放弃操作,并且弹出一条失败提示。

运行效果图:
在这里插入图片描述

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

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

相关文章

WordPress集成Argon主题[CentOS7]

下载 Argon主题 https://gitcode.net/mirrors/solstice23/argon-theme/-/releases/v1.3.5?spm1033.2243.3001.5876配置并安装Argon主题 mkdir -p /home/wwwroot/default/wordpress/wp-content/uploads/ cd /home/wwwroot/default/wordpress/wp-content/uploads/# 上传并解压…

echarts自定义tooltip,给tooltip增加百分号%

1.formatter为回调函数&#xff1a; 支持返回 HTML 字符串或者创建的 DOM 实例。 (params: Object|Array, ticket: string, callback: (ticket: string, html: string)) > string | HTMLElement | HTMLElement[] 在 trigger 为 ‘axis’ 的时候&#xff0c;或者 tooltip 被…

LiveGBS流媒体平台GB/T28181常见问题-token有效期是多久如何设置token有效期有效时间接口调用token的有效时长

LiveGBS常见问题如何设置TOKEN有效时间接口调用token的有效时长 1、TOKEN有效期2、默认token有效期3、配置token_key4、如何配置一直有效的token5、动态有效期6、搭建GB28181视频直播平台 1、TOKEN有效期 调用登陆接口后&#xff0c;会获得一个token&#xff0c;默认的有效期是…

PCB封装设计指导(十四)保存并产生device文件

PCB封装设计指导(十四)保存并产生PSM和device文件 封装命名完成之后,基本上封装的建立也接近结束,如果调网表使用的是第三方网表,还需要device文件才能调入。 但是PSM文件是不管第一方和第三方网表都是需要的,下面介绍如何产生这两个文件。 打开封装文件,如下图点击Fil…

深入理解 Linux 文件系统:从根目录到用户主目录

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

存储过程——用户自定义变量、局部变量

1.用户自定义变量 在会话一定义的变量在会话二中是用不了的。 使用set指令定义变量,并为变量赋值&#xff0c;mysql中赋值推荐使用 :&#xff0c;因为在mysql中没有这个比较运算&#xff0c;也带有比较运算的功能&#xff0c;因此赋值运算推荐使用 : set myname itcast; se…

一条sql搞崩了整个业务 ai问答

事件起因&#xff0c;我的小伙伴群里有个人发了这么一个消息 我去分析了一下原因&#xff08;&#xff09;&#xff0c;有不同观点评论区评论 使用连接且连接条件都唯一 不使用连接且where条件都唯一

【java】【面对对象高级1】static

目录 1、static修饰成员变量 1.1 修饰成员变量 1.2 成员变量的执行原理 2、static修饰成员变量的应用场景 3、static修饰成员方法 3.1 修饰成员方法 3.2 成员方法的执行原理 4、static修饰成员方法的应用场景 4.1 MyUtil工具类 4.2 main 5、static的注意事项 5.1 类方法…

Vue中TodoList案例_编辑

nextTick: MyItem.vue 加一个编辑按钮&#xff0c;input框&#xff1a;blur失去焦点时触发事件handleBlur&#xff0c;ref获取真实dom&#xff1a; <inputtype"text"v-show"todo.isEdit":value"todo.title"blur"handleBlur(todo,$even…

Access violation at address. Read of address FFFFFFC

常规的数据操作&#xff1a; 见上图&#xff0c;数据保存在.ClientDataSet1数据集中&#xff0c;为了将参数逐条保存在Txt文件中&#xff0c;做了对ClientDataSet&#xff08;DBGridEh&#xff09;的循环写盘和读盘操作&#xff1a; 但是&#xff0c;原代码通过数据集循环 &…

IP 服务级别协议监控

工作场所分布在全球多个地点的企业通过 WAN 链接共享和接收数据&#xff0c;这需要跨广泛的网络位置和路径持续监控网络质量&#xff0c;以实现优化的性能水平和不间断的服务交付。 IP 服务水平协议 IP 服务级别协议 &#xff08;IP SLA&#xff09; 是一种网络测量技术&…

php开发实战分析(10):城市区县联动筛选

php开发实战分析系列目录 php开发实战分析(1)&#xff1a;mysql操作字段&#xff08;添加、删除、修改&#xff0c;多数据表中新增多个字段&#xff09;php开发实战分析(2)&#xff1a;cookie的动态使用&#xff08;设置、获取、删除、猜你喜欢原理、购物车调用&#xff09;ph…

热烈祝贺埃文科技荣获CCF第38届中国计算机应用大会计算机应用科学技术二等奖

2023年7月16-19日&#xff0c;第38届中国计算机应用大会&#xff08;CCF NCCA 2023&#xff09;暨2023年人工智能&#xff0b;应用学术会议在江苏苏州举办。埃文科技董事长兼总经理王永博士受邀出席智慧网安论坛&#xff08;一&#xff09;数据要素市场化&#xff0c;并发表《智…

本地私有仓库部署、docker--harbor私有仓库部署和管理

部署本地私有仓库 拉取镜像 修改daemon.json配置文件 重启docker服务 创建容器 为镜像打标签 上传镜像 查看私有仓库 其他主机拉取私有仓库镜像 Docker--harbor私有仓库 &#xff08;1&#xff09;什么是Harbor Harbor 是 VMware 公司开源的企业级 Docker Registry 项目…

React Dva项目中.roadhogrc.mock.js直接自动导入mock目录下所有文件方式

上文 React Dva项目中模仿网络请求数据方法 中&#xff0c;我们书写了Dva项目模拟后端数据的方式 但是 我们.roadhogrc.mock.js中的这个处理其实并不好用 我们还需要一个一个的引入 我们可以直接靠一段代码 import fs from fs; import path from path; const mock {} fs.re…

VarHandle:Java9中保证变量读写可见性、有序性、原子性利器

文章目录 一、什么是VarHandle0、JMM1、jdk9之前无锁技术的实现 二、VarHandle使用1、VarHandle 快速上手2、VarHandle常用方法3、实战案例1&#xff1a;解决可见性&#xff08;比volatile轻量&#xff09;4、实战案例2&#xff1a;解决指令重排序&#xff08;比volatile轻量&a…

3dsmax制作一个小人

文章目录 步骤起阶五官手臂短袖添加头发、头饰BodyPaint软件贴图导入到3dsmax 渲染 步骤 起阶 五官 手臂 短袖 添加头发、头饰 BodyPaint软件贴图 寻找网络贴图&#xff0c;用PS切割&#xff0c;用BodyPaint恢复纹理 导入到3dsmax 渲染

【干货防踩坑/全图文分步/Gitlab镜像仓库自动同步】Gitlab CE/EE镜像仓库的配置技巧(含ssh/密码两验证方法)

【干货踩坑】Gitlab CE/EE镜像仓库的配置技巧&#xff08;含ssh/密码两验证方法&#xff09; 众所周知&#xff0c;Gitlab是个好东西。为什么呢&#xff1f;GitHub没有的功能&#xff0c;他全有了。更何况还可以私有部署。这两天自己部署了Gitlab&#xff0c;然后想把自己的项…

springboot + redis + 注解 + 拦截器 实现接口幂等性校验

一、概念 幂等是一个数学与计算机学概念&#xff0c;在数学中某一元运算为幂等时&#xff0c;其作用在任一元素两次后会和其作用一次的结果相同。在计算机中编程中&#xff0c;一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 幂等函数或幂等方法是…

【C++杂货铺】内存管理

文章目录 一、C/C内存分布二、C内存管理方式2.1 new和delete操作内置类型2.2 new和delete操作自定义类型 三、operator new与operator delete函数四、new和delete的实现原理4.1 内置类型4.2 自定义类型 五、定位new表达式&#xff08;placement-new&#xff09;六、malloc/free…