繁体   English   中英

ActivityResultContracts.TakePicture - 活动方向更改后不保存图像

[英]ActivityResultContracts.TakePicture - Image is not saved after activity orientation change

我正在使用活动结果 API(使用 FileProvider)将图像从相机保存到应用程序缓存文件夹,然后将其 URI 传递给另一个活动。

如果活动方向在操作过程中没有改变,它就会起作用。

但是当用户旋转 Camera 活动(由 ActivityResultContracts.TakePicture 合约启动)时 - 图像将不会被保存(创建的文件为 0 字节)。 在传递 URI 的活动中解码图像时出现错误:

android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.

我试图以明显的方式解决问题 - 在相机回调启动之前以编程方式锁定方向并在之后解锁,但这只在第一次有效(可能听起来很奇怪,但就是这样),当方向再次改变时 - 问题仍然存在。 看起来在更改方向后,当前活动结果回调与 Camera 活动之间的连接断开了。 经过研究,事实证明,如果我不启动打开图像的活动 - 图像会正确保存。 我试图在另一个线程中延迟启动活动 - 但没有成功。

我仍然找不到方向改变时图像无法保存的原因。

截屏

主要活动:

class MainActivity : AppCompatActivity() {
    private val tmpImageUri by lazy { FileUtils.getTmpFileUri(applicationContext) }
    
    private val takeImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
        if (isSuccess) {
            // We have successfully (actually no) saved the image and can work with it via tmpImageUri
            launchEditActivity(tmpImageUri)
        }
    }

    private fun takePictureFromCamera() {
        takeImageResult.launch(tmpImageUri)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.button.setOnClickListener {
            takePictureFromCamera()
        }
    }

    private fun launchEditActivity(uri: Uri){
        val intent = Intent(this, EditActivity::class.java).apply {
            data = uri
        }
        startActivity(intent)
    }
}

我通过 URI 的活动:

class EditActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        loadImage()
    }

    private fun loadImage(){
        intent.data?.let { uri ->
            model.viewModelScope.launch(Dispatchers.IO) {
                val bitmap = FileUtils.loadBitmapFromUri(applicationContext, uri)
                runOnUiThread {
                    model.setImage(bitmap)
                }
            }
        }
    }
}

文件实用程序:

fun getTmpFileUri(context: Context): Uri {
    clearCache(context)
    val tmpFile = File.createTempFile("tmp", ".jpg", context.cacheDir)
    return FileProvider.getUriForFile(context, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
}

private fun clearCache(context: Context){
    context.cacheDir.deleteRecursively()
}

fun loadBitmapFromUri(context: Context, uri: Uri): Bitmap{
    val bitmap: Bitmap = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        val src = ImageDecoder.createSource(context.contentResolver, uri)
        ImageDecoder.decodeBitmap(src) { decoder, info, source ->
            decoder.isMutableRequired = true
        }
    } else {
        MediaStore.Images.Media.getBitmap(context.contentResolver, uri)
    }
    return bitmap
}

问题出在tmpImageUri变量中,该变量在方向更改时被重置。 savedInstance中保存并恢复它之后,一切都开始正常工作。 感谢@Selvin 的帮助。

固定主要活动:

class MainActivity : AppCompatActivity() {
    companion object {
        private const val KEY_TMP_FILE_URI = "tmpFileUri"
    }

    private var tmpImageUri: Uri? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        tmpImageUri =
            if(savedInstanceState?.containsKey(KEY_TMP_FILE_URI) == true)
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
                    savedInstanceState.getParcelable(KEY_TMP_FILE_URI, Uri::class.java)
                else savedInstanceState.getParcelable(KEY_TMP_FILE_URI)
            else FileUtils.getTmpFileUri(applicationContext)
        ...
    }

    private val takeImageResult = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
        if (isSuccess) {
            tmpImageUri?.let { launchEditActivity(it) }
        }
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putParcelable(KEY_TMP_FILE_URI, tmpImageUri)
    }
    ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM