【问题标题】:Navigate to another fragment when picture is taken and saved with CameraX使用 CameraX 拍摄并保存照片时导航到另一个片段
【发布时间】:2021-12-30 01:50:43
【问题描述】:

目标很简单。当用户在 Fragment1 上拍照并保存图片时,应用程序应将用户导航到 Fragment2。我的问题,我不知道如何实现它。我无法从相机线程导航(这是非法的),我需要从主线程进行导航。但是,在主线程中,我不知道相机线程何时完成。所以基本上,我应该在哪里/如何实现它。我尝试了很多不同的解决方案,但对我没有任何效果,这就是我寻求社区帮助的原因。提前致谢。我的相机代码很简单。

    private fun takePhoto() {

    // Get a stable reference of the modifiable image capture use case
    imageCapture?.let { imageCapture ->

        // Create output file to hold the image
        val fileName = SimpleDateFormat(FILENAME, Locale.US).format(System.currentTimeMillis()) + PHOTO_EXTENSION
        val photoFile = File(outputDirectory, fileName)

        // Setup image capture metadata
        val metadata = ImageCapture.Metadata().apply {

            // Mirror image when using the front camera
            //isReversedHorizontal = lensFacing == CameraSelector.LENS_FACING_FRONT
        }

        // Create output options object which contains file + metadata
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile)
            .setMetadata(metadata)
            .build()

        // Setup image capture listener which is triggered after photo has been taken
        imageCapture.takePicture(
            outputOptions, cameraExecutor, object : ImageCapture.OnImageSavedCallback {
                override fun onError(e: ImageCaptureException) {
                    Log.e(TAG, "Photo capture failed: ${e.message}", e)
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    val savedUri = output.savedUri ?: Uri.fromFile(photoFile)

                    Log.d(TAG, "Photo capture succeeded: $savedUri")

                    // If the folder selected is an external media directory, this is
                    // unnecessary but otherwise other apps will not be able to access our
                    // images unless we scan them using [MediaScannerConnection]
                    val mimeType = MimeTypeMap.getSingleton()
                        .getMimeTypeFromExtension(savedUri.toFile().extension)
                    MediaScannerConnection.scanFile(
                        context,
                        arrayOf(savedUri.toFile().absolutePath),
                        arrayOf(mimeType)
                    ) { _, uri ->
                        Log.d(TAG, "Image capture scanned into media store: $uri")
                    }

                    saveToFireStoreStorage(photoFile, fileName)
                    //remove file from app-specific storage, keep file only on Firestore
                    photoFile.delete()
                }
            })

        // We can only change the foreground Drawable using API level 23+ API
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            // Display flash animation to indicate that photo was captured
            binding.root.postDelayed({
                binding.root.foreground = ColorDrawable(Color.WHITE)
                binding.root.postDelayed(
                    { binding.root.foreground = null }, ANIMATION_FAST_MILLIS)
            }, ANIMATION_SLOW_MILLIS)
        }
    }
}

我这样调用takePhoto:

binding.cameraCaptureButton.setOnClickListener {
    takePhoto()
}

我已经检查了类似的问题:Navigating to another fragment from CameraX analyze() blocks current fragment's lifecycle and freezes the UI 但我不想在应用程序中使用分析块,答案不适用于我的情况。

【问题讨论】:

    标签: kotlin android-camerax


    【解决方案1】:

    我会让 takePhoto() 函数返回一个布尔值,如果图片被保存,则返回 true,然后:

    binding.cameraCaptureButton.setOnClickListener {
        if (takePhoto()) {/* navigation logic* /}
    }
    

    【讨论】:

    • 不起作用,因为 takePhoto 下的一切都是异步线程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    相关资源
    最近更新 更多