首页 > 解决方案 > 如何从 SAF 文件选择器请求中获取文件路径和文件实例?

问题描述

我正在使用以下函数从 onActivity 结果发出请求和解码 URI。以下函数有效,但在生成最终文件之前会冻结整个屏幕几秒钟:

// Request code:

fun filePickerRequest3SAF(activity: AppCompatActivity) {
    RequestIntentBuilder(IntentInit.OPEN_DOCUMENT)     // Intent(Intent.ACTION_OPEN_DOCUMENT)
        .addOpenableCategory()//requestIntent.addCategory(Intent.CATEGORY_OPENABLE)
        .setFilteringMimeType("video/*")
        .addFlagForReadPermission() //requestIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) and requestIntent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)
        .buildAndStartActivityForResult(activity)
}


//response function. here I pass received intent's URI and activity context



fun getPathFromUriOrEmpty(uri: Uri?, context: Context?): String {
    if (context == null || uri == null) return ""
    return getFileFromUriOrDefault(uri, context)?.path ?: ""
}

fun getFileFromUriOrDefault(uri: Uri?, context: Context?, default:File? = null): File? {
    if (context == null || uri == null) return default
    val resolver = context.contentResolver
    val tmpFile = File(context.cacheDir, getFileNameFromUriOrNull(uri, resolver) ?: "temp_file_name.${getExtensionFromUriOrDefault(uri, context)}")
    return try {
        val inputStream = context.contentResolver.openInputStream(uri)
        val outputStream = FileOutputStream(tmpFile)
        outputStream.use { fileOut -> inputStream?.copyTo(fileOut) }
        tmpFile
    } catch (t: Throwable) {
        t.printStackTrace()
        default
    }
}



除了制作文件并将其整体复制之外,有没有办法做得更好?我的应用程序应该上传大小 > 1-2 gb 的视频,那么有没有办法我们可以在不实际制作文件副本的情况下向上传服务提供 URI / 文件?我假设文件上传服务也将制作多个副本上传

Ps:我打算支持 android 版本 KitKat 到 android 12/+ ,所以如果 SAF 可以避免它们作为跨不同 android 版本的统一解决方案,则不要考虑使用旧存储或其他此类标志

标签: androidkotlinstorage-access-frameworkandroid-storage

解决方案


推荐阅读