资讯专栏INFORMATION COLUMN

Android运行时权限

walterrwu / 642人阅读

摘要:只要在中声明即可,系统自动授权。危险权限可能会访问用户隐私数据的权限。最后附上完整的运行时权限申请示例权限已授权授权已经被拒绝过了,可以向用户说明权限用途权限作用说明我知道了授权成功授权失败

Android运行时权限
参考网址:在运行时请求权限

在Android6.0之前应用请求权限都是在应用安装时将所有权限清单展示给用户,当用户选择安装就默认允许应用请求的所有权限,而Android6.0(API级别23)以后google修改权限请求的方式,首先将权限分为两类:

正常权限:不会给用户带来隐私风险的权限。只要在AndroidManifest.xml中声明即可,系统自动授权。

危险权限:可能会访问用户隐私数据的权限。需要先在AndroidManifest.xml中声明,然后在使用之前通过用户手动授权。

关于权限的分类请参考官网文档:系统权限

新的权限管理分为以下两种情况:

如果手机系统低于Android6.0或者应用的targetSdkVersion低于23,还是按照老的权限管理方式:在AndroidManifest.xml声明的所有权限都会在应用安装时以清单的形式展现给用户,如果用户同意安装就通过了所有的权限申请。

如果手机系统为Android6.0以上并且应用的targetSdkVersion等于或者高于23,就会按照新的权限管理方式:在AndroidManifest.xml中声明的正常权限系统将会系统授权,而危险权限就需要应用在使用权限之前请求用户授权。

注意:当手机系统为Android6.0以上但是应用的targetSdkVersion低于23虽然采用的是安装时授权,但是用户依然可以在设置中手动关闭应用的权限,所以应用开发依然需要考虑缺失某些权限的情况

接下来看看应用是如何检查和请求用户授权的:

检查授权:使用ContextCompat.checkSelfPermission方法检查Activity是否获得授权,返回值PackageManager.PERMISSION_GRANTED表示已获得授权,PackageManager.PERMISSION_DENIED表示未获得授权,示例代码如下:

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);
if (PackageManager.PERMISSION_GRANTED == permissionCheck) {
    // 已授权
} else {
    // 未授权,需要请求用户授权
}

申请权限:使用ActivityCompat.requestPermissions方法动态申请权限,示例代码如下:

final static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;

ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);

获取权限申请结果:通过ActivityonRequestPermissionsResult回调获取申请结果,示例代码如下:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE == requestCode) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 用户授权通过
        } else {
            // 用户拒绝授权
        }
    }
}

判断用户是否拒绝过授权:用户拒绝授权可能是因为不了解应用获取权限的目的,所以google推荐开发者在用户拒绝授权之后再次请求权限之前可以向用户说明申请权限的目的有利于用户通过授权,可以通过ActivityshouldShowRequestPermissionRationale方法得知用户是否已经拒绝过授权,示例代码如下:

if (Build.VERSION.SDK_INT > 22 
&& shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    // 用户已经拒绝过授权,可以想用户说明申请权限的目的
} else {
    // 直接请求权限
}

通过上述几个步骤已经完成了一次运行时权限申请的全部过程,还有一点requestPermissions方法请求权限的时候,系统唤起的dialog上显示的是开发者所申请权限的权限组的信息,同一个权限组的权限只需要申请一次一旦用户授权通过应用就会获取整个权限组的授权,再次请求同组的其它权限系统会自动授权,理论上来说同组权限只需要申请一次,但是goole的官方文档上依然推荐开发者为每个权限多带带申请授权,因为在之后的版本升级中权限的分组可能会发生改变。

最后附上完整的运行时权限申请示例:

class MainActivity : AppCompatActivity() {
    val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1

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

        button.setOnClickListener({
            val permissionCheck = ContextCompat.checkSelfPermission(this@MainActivity,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)
            if (PackageManager.PERMISSION_GRANTED == permissionCheck) {
                Toast.makeText(this@MainActivity, "权限已授权", Toast.LENGTH_SHORT).show()
            } else {
                if (Build.VERSION.SDK_INT > 22 && shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                    Toast.makeText(this@MainActivity, "授权已经被拒绝过了,可以向用户说明权限用途", Toast.LENGTH_SHORT).show()
                    AlertDialog.Builder(this@MainActivity)
                            .setMessage("权限作用说明")
                            .setPositiveButton("我知道了", { dialog, which ->
                                requsetPermission()
                            })
                            .create().show()
                } else {
                    requsetPermission()
                }
            }
        })
    }

    private fun requsetPermission() {
        ActivityCompat.requestPermissions(this@MainActivity, Array(1) { Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
        if (requestCode == PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this@MainActivity, "授权成功", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this@MainActivity, "授权失败", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/14286.html

相关文章

  • 不可错过的android好文 - 收藏集 - 掘金

    摘要:针对此种情况,下文把做开发以来遇到的经典问题整理出来,希望对有需要的朋友开发工程师面试指南掘金开发工程师面试指南,作者是陶程,由梁观全贡献部分。 Android 常见问题集锦 - Android - 掘金前言:在开发中,每个人或多或少会遇到各种各样的问题,有些问题依据代码思路调试就可以定位出来,而大部分的问题都是经验性问题,遇到过就很容易解决,但在第一次遇到时往往会花费大量时间来定位问...

    derek_334892 评论0 收藏0
  • Android版本介绍 - 收藏集 - 掘金

    摘要:前言整体架构掘金概述该篇文章主要讲解的整体框架和工作流程,不会涉及到具体的实现。产品汪了解安卓的历史版本吗产品掘金最近在看的设计规范,顺便也熟悉下的版本历史。 关于 Android 7.0 适配中 FileProvider 部分的总结 - 掘金由于 Android 7.0 或更高版本的系统在国内手机市场上的占比不是很高,很多 Android 开发人员并没有做 7.0 适配工作,同时测试...

    teren 评论0 收藏0
  • Android 运行权限处理

    摘要:,本篇文章目的之一就是对运行时权限处理的一个介绍,以及对目前权限相关的库的一些了解。根据授权情况进行回调。,到此我们的运行时权限相对于早起版本的变化特点以及如何处理和封装都介绍完了。 转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/50709663;本文出自:【张鸿洋的博客】 一、概述 随着Android 6.0发布以及...

    番茄西红柿 评论0 收藏0
  • 解读Android官方开发指导 - 运行权限

    摘要:权限申请官方开发指导上使用在中已经申明的危险权限时需要用户授权。下面结合官方的开发指导对这几个做下说明。检查是否已经具有了相关权限。如,和权限就是属于组的。分门别类不仅仅是为了方便容易阅读,组内权限在申请上也是有关联的。 showImg(https://segmentfault.com/img/remote/1460000006962053); 系统权限简介 Android出于系统稳定...

    stackvoid 评论0 收藏0
  • Android M 新的运行权限开发者需要知道的一切

    摘要:取而代之的是,不得不在运行时一个一个询问用户授予权限。尽管不会调用这个函数时崩溃,返回值或者可能接下来依然导致崩溃。新运行时权限已经在棉花糖中被使用了。 英文: http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en译文:http...

    Lionad-Morotar 评论0 收藏0

发表评论

0条评论

walterrwu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<