文章目录

  • 一、前言
  • 二、AndroidManifest.xml
  • 三、核心权限申请
  • 四、使用方式
  • 五、拓展资料
  • 五、参考链接

一、前言

Android低版本使用存储功能的时候,仅需要在AndroidManifest.xml中声明权限即可使用File进行访问,然而从5.0开始存储权限去要用户进行动态授权。到了10.0开始,Android开始要求使用SAF文档框架进行存储功能的使用,11.0开始禁止用户访问Android/data/目录,到了12.0开始,存储卡的最外层目录无法使用SAF框架获取。最近在开发过程中,需要同时访问多个根目录下面的文档,倘若使用SAF获取的话那么需要用户频繁授权。经过最终调研发现了只要用户授予以下权限,依然可以正常的使用File类进行访问。并且在Android12上面依然可以和低版本一样使用。该方式可以实现文档管理器功能

二、AndroidManifest.xml

需要添加以下权限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /><applicationandroid:allowBackup="true"android:preserveLegacyExternalStorage="true"android:requestLegacyExternalStorage="true"></application>

三、核心权限申请


@file:JvmName("PermissionUtils")
package com.rockey.clean.common.fileproviderutilimport android.Manifest
import android.app.AppOpsManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity// AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE is a @SystemAPI at the moment
// We should remove the annotation for applications to avoid hardcoded value
const val MANAGE_EXTERNAL_STORAGE_PERMISSION = "android:manage_external_storage"
const val NOT_APPLICABLE = "N/A"
const val MANAGE_EXTERNAL_STORAGE_PERMISSION_REQUEST = 1
const val READ_EXTERNAL_STORAGE_PERMISSION_REQUEST = 2fun getStoragePermissionName(): String {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {MANAGE_EXTERNAL_STORAGE_PERMISSION} else {Manifest.permission.READ_EXTERNAL_STORAGE}
}fun openPermissionSettings(activity: AppCompatActivity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {requestStoragePermissionApi30(activity)}else {activity.startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,Uri.fromParts("package", activity.packageName, null)))}
}fun getLegacyStorageStatus(): String {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {Environment.isExternalStorageLegacy().toString()} else {NOT_APPLICABLE}
}fun getPermissionStatus(activity: AppCompatActivity): String {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {checkStoragePermissionApi30(activity).toString()} else {checkStoragePermissionApi19(activity).toString()}
}fun checkStoragePermission(activity: FragmentActivity): Boolean {return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {checkStoragePermissionApi30(activity)} else {checkStoragePermissionApi19(activity)}
}fun requestStoragePermission(activity: FragmentActivity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {requestStoragePermissionApi30(activity)}// If you want to see the default storage behavior on Android Q once the permission is granted// Set the "requestLegacyExternalStorage" flag in the AndroidManifest.xml file to falseelse {requestStoragePermissionApi19(activity)}
}@RequiresApi(30)
fun checkStoragePermissionApi30(activity: FragmentActivity): Boolean {val appOps = activity.getSystemService(AppOpsManager::class.java)val mode = appOps.unsafeCheckOpNoThrow(MANAGE_EXTERNAL_STORAGE_PERMISSION,activity.applicationInfo.uid,activity.packageName)return mode == AppOpsManager.MODE_ALLOWED
}@RequiresApi(30)
fun requestStoragePermissionApi30(activity: FragmentActivity) {//val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)//以下方式可以跳转至指定的应用的设置页面,上面的Action无法做到try {val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)intent.data = Uri.parse("package:" + activity.packageName)//添加包名的方式使用这种方式//    intent.data = Uri.fromParts("package", activity.packageName, null); 这种方式也是可以的activity.startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_PERMISSION_REQUEST)} catch (e: Exception) {try {activity.startActivityForResult(Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION), MANAGE_EXTERNAL_STORAGE_PERMISSION_REQUEST)} catch (e: Exception) {}}
//以下两种写法会出问题,需要注意
//    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
//    intent.data = Uri.parse("package:" + activity.packageName)
//    activity.startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_PERMISSION_REQUEST)
// 和
//        val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
//        activity.startActivityForResult(intent, MANAGE_EXTERNAL_STORAGE_PERMISSION_REQUEST)
}@RequiresApi(19)
fun checkStoragePermissionApi19(activity: FragmentActivity): Boolean {val status =ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE)return status == PackageManager.PERMISSION_GRANTED
}@RequiresApi(19)
fun requestStoragePermissionApi19(activity: FragmentActivity) {val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)ActivityCompat.requestPermissions(activity,permissions,READ_EXTERNAL_STORAGE_PERMISSION_REQUEST)
}

四、使用方式

具体使用方式如下:

    private fun initStorePermission(){val isHasPermission = checkStoragePermission(requireActivity())if (!isHasPermission){//假如没有权限则进行授权判断requestStoragePermission(requireContext())}else{//已经授权成功}}

五、拓展资料

ACTION_GET_CONTENT和ACTION_OPEN_DOCUMENT之间的真正区别是什么?
android 调用系统文件管理器(打开手机自带的文件管理器)
ACTION OPEN DOCUMENT TREE only returns empty Recent folder

五、参考链接

  1. storage-samples/FileManager at main · android/storage-samples · GitHub

Android文档管理器相关推荐

  1. Oracle Primavera Unifier文档管理器(Document Manager)

    目录 引言 介绍 引言 在 Oracle Primavera Unifier 中,文档管理器维护项目的所有文件和文档.每个项目/外壳都包含自己的文档管理器,另一个文档管理器驻留在公司级别.管理员确保员 ...

  2. 免费 epub 阅读器与文档管理器

    最近发现了一个比较好用的 pdf.epub 文件阅读器(虽然用 WPS 也可以阅读)-- Adobe Digital Editions,下载地址如下: https://www.adobe.com/so ...

  3. php开源文档共享,几款常见的PHP开源文档管理系统介绍_PHP教程

    我们在通过对WebShare WebShare是一个采用Ajax+PHP技术开发的webFTP资源管理器.可以利用它来查看,复制,修改,新增和共享Web文档. OpenGoo PHP开源文档管理系统 ...

  4. 标准功能模块组件 -- “文档管理组件,网络文档管理,网络存储”,B/S版本组件可独立运行,也可集成到其他项目里,数据结构清晰思路严谨

    可以在服务器上注册用户,审核通过后,可以在服务器上上传文档.创建目录,设置为共享的文档别人可以浏览下载. 每个用户有空间大小限制,管理员可以统一管理文档,普通用户只能管理自己的文档,可以架设多个文件服 ...

  5. 几款常见的PHP开源文档管理系统介绍

    我们在通过对PHP语言的学习中的,这是一个基于嵌入式的开源语言,那么基于PHP的开源文档管理系统自然也不在少数,今天我们就向大家推荐几款常见的PHP开源文档管理系统. 探讨PHP5多态性的具体实现方式 ...

  6. ElasticSearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解...

    墨墨导读:之前我们分享了ElasticSearch最全详细使用教程:入门.索引管理.映射详解,本文详细介绍ElasticSearch的索引别名.分词器.文档管理.路由.搜索详解. 一.索引别名 1. ...

  7. 全文检索引擎ElasticSearch:文档管理、集成IK分词器

    ElasticSearch 文档管理 添加文档 修改文档 删除文档 文档的查询 IK分词器安装 使用IK分词器 文档管理 添加文档 定位到资源 url http://localhost:9200/{i ...

  8. elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解

    一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 ...

  9. elasticsearch系列三:索引详解(分词器、文档管理、路由详解(集群))

    目录 一.分词器​ 1. 认识分词器 1.1 Analyzer 分析器 1.2 如何测试分词器 2. 内建的字符过滤器(character filter) 2.1 HTML过滤字符过滤器(HTML S ...

最新文章

  1. 百度指数常见php框架,怎么导出数据到excel表格-如何将百度指数数据导出到Excel表格...
  2. 世界欠他一个图灵奖! LSTM之父的深度学习“奇迹之年”
  3. css3中实现摘取金币_用css3实现抽奖转盘里的扇形图
  4. 一级计算机word试题及答案,计算机一级考试试题及答案Word文档..doc
  5. 操作系统习题7—文件系统
  6. 19、Power Query-快速分析各产品的销售情况
  7. 一个SAP老司机多年的中间件使用心得
  8. python queue的用法_python Queue模块使用
  9. 搭建接口自动化测试框架详细过程
  10. 全新开发萝卜影视源码金色版 视频影视系统APP源码
  11. 记忆训练: 记数字 (110数字图像编码)
  12. ks检验正态分布结果_看SPSS如何检验数据是否服从正态分布
  13. Wretch超雅虎奇摩成台湾省第一大网站
  14. 国外 2D 游戏引擎相关站点
  15. 爆流的随便画教程—NO12 画嘞个剑
  16. android u盘加载_[转] android 通过usb读取 U盘
  17. PMS进化论:回顾过去才能更好地看向未来!
  18. 使用 Swift 语言编程的优缺点
  19. nginx常用的优化配置
  20. Blo Tx Pending

热门文章

  1. 获取局域网远程主机ipv6地址
  2. redis主从、哨兵、集群
  3. 有哪些翻译视频声音的软件?1分钟教会你视频翻译的技巧
  4. [iOS开发]@autoreleasepool原理探究
  5. 【资源】公开的电子书 合集 (计算机相关、多高清、pdf)
  6. 做技术应该持有什么样的工作态度?
  7. uniapp中app分享小程序方法
  8. 腾讯乐固自动加固插件
  9. 苹果所用应用打不开怎么办?论浮标有多重要?
  10. DevC++实现代码高亮复制进word