Android Q Download文件存储

11 以上 存放 Download 目录中 只能通过uri 进行读取 且只能APP 安装后存放的文件 才有访问权限

APP 卸载之后 数据库中权限会被移除 无法再通过文件名称进行查询

这边通过比较描述字段进行判断是否下载过文件

11 以上APP进行卸载后在安装下载 会出现重复文件

不知是否还有其他解决方案

  1. 将文件下载至缓存目录中

  2. 复制文件至Download目录中

    复制代码
    fun copyFileToDownload(context:Context, oldPath:String, targetDirName:String) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            copyFileToDownloadDir(context, oldPath, targetDirName)
        } else {
            var newPath = FileUtils.getExternalDownloadsPath() + File.separator +targetDirName + File.separator + File(oldPath).name
            var filePara = File(FileUtils.getExternalDownloadsPath() + File.separator + targetDirName)
            if (filePara.exists()) {
                filePara.mkdirs()
            }
            FileUtils.copyFile(oldPath, newPath)
        }
    }
    
     @RequiresApi(Build.VERSION_CODES.Q)
    fun copyFileToDownloadDir(context:Context, oldPath:String, targetDirName:String):Uri? {
        try {
            val oldFile = File(oldPath)
            //设置目标文件的信息
            val values = ContentValues()
            values.put(MediaStore.Images.Media.DESCRIPTION, oldFile.name)
            values.put(MediaStore.Files.FileColumns.DISPLAY_NAME, oldFile.name)
            values.put(MediaStore.Files.FileColumns.TITLE, oldFile.name)
            values.put(MediaStore.Files.FileColumns.MIME_TYPE, oldPath.getMimeType())
            val relativePath = Environment.DIRECTORY_DOWNLOADS + File.separator + targetDirName
            values.put(MediaStore.Images.Media.RELATIVE_PATH, relativePath)
            val downloadUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
            val resolver = context.contentResolver
            val insertUri = resolver.insert(downloadUri, values)
            if (insertUri != null) {
                val fos = resolver.openOutputStream(insertUri)
                if (fos != null) {
                    val fis = FileInputStream(oldFile)
                    fis.copyTo(fos)
                    fis.close()
                    fos.close()
                    return insertUri
                }
            }
        } catch (e:Exception) {
            e.printStackTrace()
        }
        return null
    }
  3. 通过查询 DESCRIPTION字段判断文件是否存在

    复制代码
    fun findDownloadsFile(context:Context,targetDirName:String, description:String):ArrayList<Uri>? {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
             return findDownloadsUri4Description(context,targetDirName, description)
         } else {
             var newPath = FileUtils.getExternalDownloadsPath() + File.separator + targetDirName + File.separator + description
             var file = File(newPath)
             if (file.exists()) {
                 var uri = FileUtils.getFile2Uri(file)
                 var list = ArrayList<Uri>()
                 uri?.let { list.add(it) }
                 return list
             } else {
                 return null
    
             }
         }
     }
         /**
      *  通过描述 字段 查询 下载目录中的文件
      * @param context Context
      * @param dirName String?  子目录
      * @param description String  描述字段
      * @return ArrayList<Uri>
      */
     @RequiresApi(Build.VERSION_CODES.Q)
     fun findDownloadsUri4Description(context:Context, dirName:String?, description:String):ArrayList<Uri> {
         val resultList = ArrayList<Uri>()
         try {
             val resolver = context.contentResolver
             val downloadUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI
             var selection:String? = null
    
             var selectionArgs = mutableListOf<String>()
             if (dirName != null && dirName.isNotEmpty()) {
                 selection = MediaStore.Files.FileColumns.BUCKET_DISPLAY_NAME + " = ? AND "
                 selectionArgs.add(dirName)
             }
             selection = selection + MediaStore.Images.Media.DESCRIPTION + " = ? "
             selectionArgs.add(description)
    
             val resultCursor = resolver?.query(downloadUri, null, selection, selectionArgs.toTypedArray(), null)
             if (resultCursor != null) {
                 val fileIdIndex = resultCursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
                 while (resultCursor.moveToNext()) {
                     val fileId = resultCursor.getLong(fileIdIndex)
                     val pathUri = downloadUri.buildUpon().appendPath("$fileId").build()
                     resultList.add(pathUri)
                 }
                 resultCursor.close()
             }
         } catch (e:Exception) {
             e.printStackTrace()
         }
         return resultList
     }
相关推荐
计算机毕设定制辅导-无忧学长4 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
程序员柳5 小时前
基于微信小程序的校园二手交易平台、微信小程序校园二手商城源代码+数据库+使用说明,layui+微信小程序+Spring Boot
数据库·微信小程序·layui
梦在深巷、5 小时前
MySQL/MariaDB数据库主从复制之基于二进制日志的方式
linux·数据库·mysql·mariadb
IT乌鸦坐飞机5 小时前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
IT_10245 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
祁思妙想7 小时前
八股学习(三)---MySQL
数据库·学习·mysql
惊骇世俗王某人7 小时前
1.MySQL之如何定位慢查询
数据库·mysql
秦歌6668 小时前
向量数据库-Milvus快速入门
数据库·milvus
Edingbrugh.南空9 小时前
Flink SQLServer CDC 环境配置与验证
数据库·sqlserver·flink
码不停蹄的玄黓9 小时前
MySQL分布式ID冲突详解:场景、原因与解决方案
数据库·分布式·mysql·id冲突