ActivityResultContracts.TakePicture() loses uri when rotating screen

Viewed 313

I am building an app that calls an activity to analyze a photo. once that activity starts it launches the camera or gallery depending on the value of "capture" or "gallery". the problem is: I want to keep the activity orientation in portrait but the camera follows the phone orientation and after taking the photo it loses everything and starts the camera again OnResume again and again. if I held the phone vertically and captured the pic everything works fine and the pic appears in Any changing of the rotation gets me error W/ImageView: Unable to open content: content://com.myProject.projecttwo.provider/external/Android/media/com.myProject.projecttwo/projectTwo/2021-07-31-17-59-19-4262257504715507656821.jpeg

import android.content.Context
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.FileProvider
import androidx.lifecycle.lifecycleScope
import java.io.File
import java.text.SimpleDateFormat
import java.util.*

class PhotoAnalysis : AppCompatActivity() {

    private var receivedUriKey: Uri? = null
    private lateinit var outputDirectory: File
    //private var selection: String? = null
    private var selection: String? = "capture" /* later will get it from clicks*/
    private lateinit var imageView: ImageView

    private val pickerContent = registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->
        if(uri != null) { receivedUriKey = uri}
    }

    private val capturePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) {
        if(it) {
            receivedUriKey.let { uri ->
                if( uri != null) {
                    receivedUriKey = uri
                    Log.d("Capture Pic", receivedUriKey.toString())
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_photo_analysis)

        imageView = findViewById(R.id.result_image_view)

    }

    override fun onResume() {
        super.onResume()

        if( selection == "gallery" && receivedUriKey == null) {
            pickerContent.launch("image/*")
        } else if(selection == "capture" && receivedUriKey == null) {
            Log.d("Capture Resume", receivedUriKey.toString())
            takeImage()
        }
        if(receivedUriKey != null) {
            Log.d("Capture Resume 2", receivedUriKey.toString())
            imageView.setImageURI(receivedUriKey)
        }
    }


    private fun takeImage() {
        lifecycleScope.launchWhenStarted {
            getTmpFileUri().let { uri ->
                receivedUriKey = uri
                capturePicture.launch(uri)
            }
        }
    }

    private fun getTmpFileUri(): Uri {
        outputDirectory = getOutputDirectory(this)
        val tmpFile = File.createTempFile(
            SimpleDateFormat(FILENAME, Locale.ENGLISH).format(System.currentTimeMillis()), PHOTO_EXTENSION, outputDirectory).apply {
            createNewFile()
            deleteOnExit()
        }
        return FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.provider", tmpFile)
    }

    companion object {
        private const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS"
        private const val PHOTO_EXTENSION = ".jpeg"

        private fun getOutputDirectory(context: Context): File {
            val appContext = context.applicationContext
            val mediaDir = context.externalMediaDirs.firstOrNull()?.let {
                File(it, appContext.resources.getString(R.string.app_name)).apply { mkdirs() } }
            return if (mediaDir != null && mediaDir.exists())
                mediaDir else appContext.filesDir
        }
    }
}
0 Answers
Related