You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 13模拟器使用ACTION_PICK选视频后黑屏问题排查

Android 13模拟器选择视频后编辑界面黑屏问题排查与解决

问题根源

  • Android 13(API 33+)对媒体文件访问权限管控更严格,直接解析content://类型Uri到绝对路径并通过FileInputStream访问,会因权限不足导致文件读取失败,最终视频无法加载显示黑屏。
  • 第三方相册(如谷歌相册)返回的content:// Uri并非直接指向本地文件路径,parsePath解析出的路径可能无效或无读取权限。
  • 传递文件路径的方式忽略了Uri的临时权限,即便添加FLAG_GRANT_READ_URI_PERMISSION,目标Activity也无法通过路径获取对应权限。

解决方案

1. 直接传递Uri而非解析后的文件路径

修改Fragment中跳转Activity的代码,直接传递选中的Uri:

R.id.imageViewVideo -> {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = "video/*"
    }
    resultLauncher.launch(intent)
}

private val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == RESULT_OK) {
        val videoUri: Uri? = result.data?.data ?: return@registerForActivityResult
        val intent = Intent(requireContext(), SelectVideoActivity::class.java).apply {
            data = videoUri
            addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        }
        startActivity(intent)
    }
}

2. 在SelectVideoActivity中通过ContentResolver读取Uri内容

替换FileInputStream为ContentResolver.openInputStream(),规避权限问题:

// 初始化inputFile逻辑保留
private lateinit var inputFile: File
inputFile = File(getExternalFilesDir("app-mnme")!!.absolutePath + "/${System.currentTimeMillis()}.mp4")

// 接收Uri并执行复制
val videoUri = intent.data ?: return
copyFile(videoUri, inputFile)

// 修改copyFile函数,接收Uri参数
@Throws(IOException::class)
fun copyFile(sourceUri: Uri, destFile: File) {
    try {
        if (!destFile.parentFile!!.exists()) destFile.parentFile!!.mkdirs()
        if (!destFile.exists()) {
            destFile.createNewFile()
        }
        contentResolver.openInputStream(sourceUri)?.use { inputStream ->
            FileOutputStream(destFile).use { outputStream ->
                inputStream.copyTo(outputStream)
            }
        } ?: throw IOException("无法打开视频输入流")
    } catch (e: Exception) {
        Log.i("error", "selectvideo ${e.message}")
    } finally {
        initViews()
        setListener()
    }
}

3. 移除不可靠的路径解析逻辑

删除parsePath相关代码,Android 13及以上版本中,解析content:// Uri到绝对路径的方式已不再可靠,且易引发权限问题。

4. 权限适配(可选)

若应用有其他媒体操作需求,在Android 13及以上版本需正确申请READ_MEDIA_VIDEO权限:

private fun requestVideoPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        requestPermissions(arrayOf(Manifest.permission.READ_MEDIA_VIDEO), 1001)
    }
}

验证要点

  • 查看copyFile函数的异常日志,确认是否仍存在读取失败情况。
  • 确保inputFile存储在应用私有外部目录,避免额外存储权限问题。

内容的提问来源于stack exchange,提问作者sejn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 21:46:20