首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >registerForActivityResult(ActivityResultContracts.TakeVideo())总是空的。

registerForActivityResult(ActivityResultContracts.TakeVideo())总是空的。
EN

Stack Overflow用户
提问于 2021-03-14 07:01:51
回答 1查看 1.2K关注 0票数 0

我使用以下代码捕获视频。一切都很好,但是在捕获视频之后,registerForActivityResult(ActivityResultContracts.TakeVideo())总是为空。捕获的视频存在于给定的路径中。我能用什么方法解决这个问题?

代码语言:javascript
复制
 private fun openCameraForMovie() {
        val packageManager = requireContext().packageManager
        Intent(MediaStore.ACTION_VIDEO_CAPTURE).also { takeVideoIntent ->
            takeVideoIntent.resolveActivity(packageManager)?.also {
                startRecording()
            }
        }
    }




 private fun startRecording() {
        try {
            val root = File(
                requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)
                    .toString() + "/media/"
            )

            if (!root.exists()) {
                root.mkdir()
            }

            val videoName = "vid_" + System.currentTimeMillis() + ".mp4"
            val sdImageMainDirectory = File(root, videoName)

            var fileUri: Uri? = FileProvider.getUriForFile(
                requireContext(),
                context?.applicationContext?.packageName + ".provider",
                sdImageMainDirectory
            ) ?: return

        
            mViewModel.videoUri.postValue(fileUri)

        } catch (ex: Exception) {
            Timber.d("startRecording ${ex.localizedMessage}")
        }
    }

此代码始终为空:

代码语言:javascript
复制
  private val recordVideoResult =
        registerForActivityResult(ActivityResultContracts.TakeVideo()) { it ->
            try {
                if (it != null) {
                    Timber.d(">>>> Video Bitmap: $it") 
                }
            } catch (ex: Exception) {
                Timber.d(">>>> Video Bitmap: ${ex.localizedMessage}")
            }
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-14 09:15:33

发生什么事了呢?

保存到提供的content-**Uri.中的视频的ActivityResultContract 返回一个缩略图。**

TakeVideo文档,强调地雷。

您不需要缩略图(反正这是可选的),您需要指向实际视频的Uri。但是您已经知道了Uri,因为您提供了它作为输入。

这次又是什么?

要做到这一点,需要采取几个步骤:

  1. 将输入的Uri存储在变量中,并正确处理保存状态,这样应用程序就知道当您从相机应用程序返回时,您一直在录制视频。
  2. 编写自定义TakeVideo协议,如果视频捕获成功,它将返回。检查非空预览Bitmap无法使用,因为预览是可选的.

它看起来可能是这样的:

代码语言:javascript
复制
private AtomicReference<Uri> recordingUri = new AtomicReference<>();

private ActivityResultLauncher<Uri> recordVideoResult =
        registerForActivityResult(new TakeVideo2(), success -> {
            final Uri uri = recordingUri.getAndSet(null);
            if (success) {
                // Do something with the video.
            }
        });

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    // ...
    if (savedInstanceState != null) {
        recordingUri.set(savedInstanceState.getParcelable("recordingUri"));
    }
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    // ...
    outState.putParcelable("recordingUri", recordingUri.get());
}

private void startRecording() {
    final Uri uri = // ...;
    recordingUri.set(uri);
    recordVideoResult.launch(uri);
}

public static class TakeVideo2 extends ActivityResultContract<Uri, Boolean> {

    @CallSuper
    @NonNull
    @Override
    public Intent createIntent(@NonNull Context context, @NonNull Uri input) {
        return new Intent(MediaStore.ACTION_VIDEO_CAPTURE)
                .putExtra(MediaStore.EXTRA_OUTPUT, input);
    }

    @Nullable
    @Override
    public final SynchronousResult<Boolean> getSynchronousResult(@NonNull Context context,
            @NonNull Uri input) {
        return null;
    }

    @Override
    public final Boolean parseResult(int resultCode, @Nullable Intent intent) {
        return resultCode == Activity.RESULT_OK;
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66621919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档