How can I use the TakePicture contract to take a p...
# compose
m
How can I use the TakePicture contract to take a picture and display it in Jetpack Compose? (Code in thread)
I'm using this code, which does not work.
Copy code
@Composable
fun MyPicker() {
    val context = LocalContext.current
    val permissionLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.RequestPermission().apply{
    }){
    }

    val imgUri by remember{mutableStateOf("${context.filesDir}/temp.jpg".toUri())}

    val captureLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.TakePicture()){
            Toast.makeText(context, "Image capture: ${if(it) "Successful" else "Failed"}", Toast.LENGTH_SHORT)
                .show()
    }

    Column {
        Button(onClick = {
            if(ContextCompat.checkSelfPermission(context, android.Manifest.permission.CAMERA) != PERMISSION_GRANTED)
                permissionLauncher.launch(android.Manifest.permission.CAMERA)
            else captureLauncher.launch(imgUri)
        }) {
            Text("Load")
        }
        Image(painter = rememberAsyncImagePainter(imgUri), null)
    }
}
i
Are you using the camera permission for something else in your app? If your app doesn't have the camera permission in your manifest at all (i.e., you remove that permission entirely), then you don't need the camera permission for the
TakePicture
contract. That would simplify your code considerably
❤️ 1
m
Oh, I thought I needed camera permission for TakePicture. But, I don't know how to prepare the uri to pass to the launch method. I get exceptions like FileUriExposedException and such for the URI i pass.
i
Look up FileProvider - a random Camera app doesn't have direct permission to write into your storage, so you need thay level of indirection
❤️ 1
s
I wonder, if we take this approach, and remove the permission completely so that we only use the activity result contract, will those old clients who have denied the permission still crash at runtime?
i
If you remove the permission from the manifest, that's enough for everything to work
s
Sounds awesome, that feels so convenient! I have to ask, is there some part of the docs that go into a bit more detail how to get this right by the way? Using the
ActivityResultContracts.TakePicture()
contract there’s some ceremony that needs to be done for all this. I’ve tried to find some part in the docs that mention how to use it but I haven’t been lucky. There’s a bunch of things to get right. How to use this xml file which will contain the <paths> <external-path> and so on, getting the right path to there, creating a file to save there, getting the right Uri to it and then properly handling everything after process death so that when you’re back on your app everything still works.
597 Views