• Android存储权限完美适配(Android11及以上适配)


    一、Bug简述

    一个很普通的需求,需要下载图片到本地,我的三个测试机(荣耀Android10,红米 11 和小米Android 13都没有问题)。

    然后,主角登场了,测试的三星Android 13 死活拉不起存储权限弹窗。

    想了下,三星的系统可能和小米的系统做了些区别。于是就是看了下存储权限的版本更迭,却是发现了些骚东西。

    二、原因

    很早以前,一直都是在manifest申明这两个权限就可以了,但是现在会有下面的警告!

    这便是错误的原因:

     可以得知,在Android 13(sdkversion为33)的系统中,已经被废弃了!!!

    但是如果你给Write和Read权限加上maxSdkVersion=32,他在11,12上是没有问题的,但是最新的App要求 target sdkversion必须是33了。

    所以,在此就必须做一个适配:

    Android 11 里将引入一个特别的权限叫做 MANAGE_EXTERNAL_STORAGE,该权限将授权读写所有共享存储内容,这也将同时包含非媒体类型的文件。但是获得这个权限的应用还是无法访问其他应用的应用专属目录 (app-specific directory),无论是外部存储还是内部存储。

    那么,为了兼容Android版本,我就必须在Android11之前和之后分开做申请才会有用。

    三、步骤

    1).申明权限

    manifest文件里:

    2).权限的判断

    判断是否已经获得权限:

    1. private fun checkPer(activity: PreViewActivity): Boolean {
    2. return if (Build.VERSION.SDK_INT >= 30) {
    3. EasyPermissions.hasPermissions(
    4. activity,
    5. android.Manifest.permission.MANAGE_EXTERNAL_STORAGE
    6. )
    7. } else {
    8. EasyPermissions.hasPermissions(
    9. activity,
    10. android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    11. )
    12. }
    13. }

    未获得权限,申请权限

    1. private fun aaa(activity: PreViewActivity, curImg: Int) {
    2. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    3. val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
    4. intent.data = Uri.parse("package:" + activity.packageName)
    5. activity.startActivityForResult(intent, 200)
    6. } else {
    7. val perm = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
    8. PaperThreeVariable.isToRequestPer = true
    9. EasyPermissions.requestPermissions(
    10. PermissionRequest.Builder(
    11. activity,
    12. 200,
    13. perm
    14. )
    15. .build()
    16. )
    17. }
    18. }

    权限申请回调

    1. override fun onRequestPermissionsResult(
    2. requestCode: Int, permissions: Array<String>, grantResults: IntArray
    3. ) {
    4. super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    5. EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
    6. }
    7. override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
    8. AppInitUtils().saveFreshAppImageToGallery(this, curImg)
    9. PaperThreeVariable.isToRequestPer = false
    10. }
    11. override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
    12. PaperThreeVariable.isToRequestPer = false
    13. if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
    14. AppSettingsDialog.Builder(this)
    15. .setRationale("This function requires storage permission to be enabled")
    16. .setNegativeButton("No")
    17. .setPositiveButton("Yes")
    18. .build().show()
    19. }
    20. }

    因为有时候用户会拒绝权限且永久弹窗,所以为了方便我就用了EasyPermission这个库,拒绝的情况下,弹窗跳转系统权限设置页面去让用户选择开启权限。

    这样,就OK啦!(至于我的小米为啥Android 13也能正常拉起,我也不知道具体原因,但是在Android Studio的历史链接设备中,我发现它识别我的手机系统为Android 12,真是百思不得其解)

    本文参考了郭霖大神的一篇文章,当时是想看下 Scoped Storage这个属性的内容,接过发现了Android 11的变更。

    Android 11新特性,Scoped Storage又有了新花样

    仅做个人工作总结,内容肯定不够全面,如有问题,欢迎大佬指正!

    Android Permission 权限申请,EasyPermission和其他三方库_安卓权限申请_&岁月不待人&的博客-CSDN博客

    补充:

    因为 MANAGE_EXTERNAL_STORAGE,该权限将授权读写所有共享存储内容,所以在谷歌中属于敏感权限,不容易通过,如果只是想保存图片,则可以通过下面的博客中的方法去保存

    Android 保存图片并刷新相册(无需权限)-CSDN博客

    Android Gilde获取网络图片显示保存路径并转化为bitmap-CSDN博客

  • 相关阅读:
    flowable工作流所有业务概念
    MVC第三波书店书籍登录展示页面
    使用Jenkins部署Git仓库微服务项目
    容联七陌:用PLG产品,重新定义客服边界
    ACREL DC energy meter Application in Indonesia
    http://39.98.219.132 题库标准答案(题库序号:1969)之母舰
    蓝桥杯倒计时48天!二分模板
    拥抱国产信创化,思迈特与云和恩墨完成产品兼容认证
    Kotlin 不可变数组和可变数组
    docker-compose:搭建酷炫私有云相册photoprism
  • 原文地址:https://blog.csdn.net/LoveFHM/article/details/132996171