android - 如何从 registerActivityResult 捕获 URI?

标签 android android-studio kotlin

我目前正在尝试在 Android 应用程序中编写一个 View ,该 View 将在按下按钮时打开相机,让用户录制视频,并将 URI 存储在附加到所述 View 的成员中。我非常希望这是可能的,但不确定,因为我找不到很多有关该问题的文档。

我在这里使用最重要的答案作为捕获 URI 的引用,它非常全面,但由于我不确定的原因在我的情况下不起作用。

我在文件顶部声明我的变量,如下

私有(private)变量 videoUri:Uri? =空

其余相关代码发生在这里:

val recordVideoResult = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { uri: Uri? ->
    uri?.let {
        this.videoUri = uri
    }
}

val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
    if (isGranted) {
        launchCamera()
    } else {
        Toast.makeText(this, "Can't open camera because permission is denied. Please provide access in settings.", Toast.LENGTH_SHORT).show()
    }
}


fun launchCamera() {
    if (packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) { // First check if camera is available in the device
        when {
            ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED -> {
                recordVideoResult.launch(this.uri)
            }
            else -> {
                // You can directly ask for the permission.
                // The registered ActivityResultCallback gets the result of this request.
                requestPermissionLauncher.launch(
                    Manifest.permission.CAMERA
                )
            }
        }
    }
}

我的 IDE 和编译器向我大喊以下错误,这对我来说看起来像是一个错误,但不会消失。 enter image description here

我非常不确定我做错了什么。如果这太明显了,请原谅我,我编写 Kotlin 还不到一周。

最佳答案

您已获得 CaptureVideo 的输入和输出混合。 CaptureVideo contract说:

An ActivityResultContract to take a video saving it into the provided content-Uri.

Returns true if the video was saved into the given Uri.

因此输入Uri - 这就是您需要传递给 launch 的内容。 输出Boolean 。这可以通过查看 class itself 来确认。 ,它显示完整的类型 - ActivityResultContract<Uri, Boolean> .

这意味着您实际需要做的是:

  1. Setup a FileProvider 。这就是生成 Uri 的方法。来自File您的应用程序拥有的适合发送到 launchCaptureVideo Intent 。您是选择视频存储位置的人,而不是相机应用。

  2. 生成适当的File与您想要保存视频的位置关联并将其存储为类中的变量,就像您之前对 videoUri 所做的那样,例如,在名为 file 的变量中(根据 note on the Launching an Intent documentation ,您可能还希望将其存储在 onSaveInstanceState() 中,以防您的进程在相机启动时被破坏)。

  3. 使用 FileProvider用于从您的 File 生成 Uri 的 API并将其传递给您对 launch 的调用.

val contentUri = FileProvider.getUriForFile(
  this, // your Activity or 
  "com.example.myapp.fileprovider", // The android:authorities value from your manifest 
  file) // The File you want to store the video into
recordVideoResult.launch(contentUri)
  • 将您的电话更改为 registerForActivityResultsuccess bool 结果:
  • val recordVideoResult = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { success ->
        if (success) {
          // Now your file contains the fully captured video
        } else {
          // The user cancelled taking a video
        }
    }
    

    关于android - 如何从 registerActivityResult 捕获 URI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74650304/

    相关文章:

    Android Studio - 如何让 R.string 在编辑器中显示文本

    android - Activity 在拆分屏幕后重新创建viewModel

    java.lang.OutOfMemoryError。安卓

    android - 如何更新谷歌播放的增量成就

    android-studio - 如何使用 react-native-navigation v2 添加 react-native-splash-screen

    android - 在android studio中有没有办法在不删除模块的情况下禁用它?

    android - 我在 kotlin 中使用 xml <include/> 标签时崩溃

    android - 回收器 View 滚动但未滚动到末尾

    java - Calendar.setTimeInMillis 错误 - 这是为什么?

    android - 如何删除标题栏和 LinearLayout 的第一个元素之间的黑色空间?