11 以上 存放 Download 目录中 只能通过uri 进行读取 且只能APP 安装后存放的文件 才有访问权限
APP 卸载之后 数据库中权限会被移除 无法再通过文件名称进行查询
这边通过比较描述字段进行判断是否下载过文件
11 以上APP进行卸载后在安装下载 会出现重复文件
不知是否还有其他解决方案
-
将文件下载至缓存目录中
-
复制文件至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 }
-
通过查询 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 }