首页 > 其他分享 >Android 运行时权限

Android 运行时权限

时间:2023-01-18 09:55:36浏览次数:40  
标签:申请 用户 CALL 授权 Android 权限 运行

Android 的权限机制,从系统的第一个版本开始就已经存在了。但其实之前 Android 的权限机制在保护用户安全和隐私等方面起到的作用比较有限,尤其是一些大家都离不开的常用软件,非常容易“店大欺客”。为此,Android 开发团队在Android 6.0 系统中引入了运行时权限这个功能

权限机制

们在AndroidManifest.xml 文件中 添加了权限声明:

<uses-permission android:name="android.permission.CALL_PHONE" />

加入了这句权限声明后,用户主要在两个方面得到了保护。

一方面,如果用户在低于Android 6.0 系统的设备上安装该程序,会在安装界面给出提醒。这样用户就可以清楚地知晓该程序一共申请了哪些权限,从而决定是否要安装这个程序。

另一方面,用户可以随时在应用程序管理界面查看任意一个程序的权限申请情况。

这种权限机制的设计思路其实非常简单,就是用户如果认可你所申请的权限,就会安装你的程序,如果不认可你所申请的权限,那么拒绝安装就可以了。 但是理想是美好的,现实却很残酷。很多我们离不开的常用软件普遍存在着滥用权限的情况,不管到底用不用得到,反正先把权限申请了再说。

Android 开发团队当然也意识到了这个问题,于是在Android 6.0 系统中加入了运行时权限功能。也就是说,用户不需要在安装软件的时候一次性授权所有申请的权限,而是可以在软件的 使用过程中再对某一项权限申请进行授权。

当然,并不是所有权限都需要在运行时申请,对于用户来说,不停地授权也很烦琐。Android 现 在将常用的权限大致归成了两类,一类是普通权限,一类是危险权限。准确地讲,其实还有一些特殊权限,不过这些权限使用得相对较少。普通权限指的是那些不会直接威胁到用户的安全和隐私的权限,对于这部分权限申请,系统会自动帮我们进行授权,不需要用户手动操作。危险权限则表示那些可能会触及用户隐私或者对设备安全性造成影响的权限,如获取设备联系人信 息、定位设备的地理位置等,对于这部分权限申请,必须由用户手动授权才可以,否则程序就 无法使用相应的功能。

到Android 10 系统为止所有的危险权限

 注意,表格中每个危险权限都属于一个权限组,我们在进行运行时权限处理时使用的是权限名。原则上,用户一旦同意了某个权限申请之后,同组的其他权限也会被系统自动授权。但是请谨记,不要基于此规则来实现任何功能逻辑,因为Android 系统随时有可能调整权限的分组。

在程序运行时申请权限

CALL_PHONE这个权限是编写拨打电话功能的时候需要声明的,因为拨打电话会涉及用户手机的资费问题,因而被列为了危险权限。

修改activity_main.xml 布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

接着修改 MainActivity 中的代码:

class MainActivity : AppCompatActivity() {

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

        makeCall.setOnClickListener {
            // 判断用户是不是已经给过我们授权了,借助的是ContextCompat.checkSelfPermission()方法。
            // checkSelfPermission()方法接收两个参数:
            // 第一个参数是Context,这个没什么好说的;
            // 第二个参数是具体的权限名,比如打电话的权限名就是Manifest.permission.CALL_PHONE。
            // 然后我们使用方法的返回值和PackageManager.PERMISSION_GRANTED做比较,相等就说明用户已经授权,不等就表示用户没有授权。
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE)
                != PackageManager.PERMISSION_GRANTED
            ) {
                // 调用ActivityCompat.requestPermissions()方法向用户申请授权。
                // requestPermissions()方法接收3个参数:
                // 第一个参数要求是Activity 的实例;
                // 第二个参数是一个String数组,我们把要申请的权限名放在数组中即可;
                // 第三个参数是请求码,只要是唯一值就可以了,这里传入了1。
                ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1)
            } else {
                call()
            }
        }
    }

    // 调用完requestPermissions()方法之后,系统会弹出一个权限申请的对话框,用户可以选择同意或拒绝我们的权限申请。
    // 不论是哪种结果,最终都会回调到onRequestPermissionsResult()方法中,而授权的结果则会封装在grantResults参数当中。
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<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 {
            // 在按钮的点击事件中,我们构建了一个隐式Intent ,Intent 的action 指定为Intent.ACTION_CALL,这是一个系统内置的打电话的动作,
            val intent = Intent(Intent.ACTION_CALL)
            intent.data = Uri.parse("tel:10086")//在data 部分指定了协议是tel ,号码是10086
            startActivity(intent)
        } catch (e: SecurityException) {
            e.printStackTrace()
        }
    }

}

接下来修改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.CALL_PHONE" />

  

 

标签:申请,用户,CALL,授权,Android,权限,运行
From: https://www.cnblogs.com/ooo0/p/17059196.html

相关文章

  • android jetpack room文章一
    此文,为room的第一篇随笔,记录room的基础使用方式。后续还会记录一些补充的内容。app.gradle导入库:dependencies{//当前targetSdk32//API33可以使用2.5.......
  • Android记录 透明状态栏+固化的沉浸模式的简单实现
    代码中实现透明状态栏的方法:publicclassMainActivityextendsAppCompatActivity{privateActivityMainBinding_binding;@Overrideprotectedvoidon......
  • Android 动态存储权限
    //检查外部存储挂载状态if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//检查读取和写入动态权限......
  • IntelliJ插件笔记(二) 运行插件---添加Actions
    本文内容主要流程按照官网手册展开,也是较为准确的翻译。原文可见:CreatingActions|IntelliJPlatformPluginSDK(jetbrains.com)Actions插件可以在IDE的菜单或者工具......
  • casbin权限模型推演
    无论什么项目只要涉及到多个用户的操作都会开始考虑权限控制,权限管理是一个很常见部分,所以出现了单独处理这个部分的开源项目,即本文要介绍的casbin项目。casbin支持很多......
  • 初步理解:jvm运行机制,java程序运行机制,堆栈详解,jvm调优的目的。
    谷咕咕最近在准备面试,本来想多看看堆和栈的关系,看看发现又设计到gc(GarbageCollection)垃圾回收机制,发现盲区太多了,就去粗略的学习了一下jvm(java虚拟机),发现之前只会写程序,底......
  • JVM:运行时数据区-PC寄存器(程序计数器)
    JVM:运行时数据区1.什么是pc寄存器:JVM的pc寄存器也叫程序计数器,是对物理pc寄存器的一种抽象虚拟。用来存储指向一下条指令的地址,即将要执行的指令代码,由执行引擎读取下一......
  • JVM :运行时数据区-虚拟机栈
    2.2虚拟机栈2.1.1概述优点:跨平台,指令集小,编译器容易实现缺点:性能下降实现同样的工能需要更多的指令集栈是运行时的单位,而堆是存储的单元是什么?每个线程在创建是辉创建一个虚......
  • 安装react脚手架,运行
    npmuninstallcreate-react-app-g(以前创建过脚手架的话先进行卸载再重新安装以适配最新版本此步骤可逃过失败也是正常现象)npminstallcreate-react-app-g安装脚手......
  • [ROC-RK3568-PC] [Firefly-Android] 10min带你了解LED的使用
    ......