In my Android app, I need to let the user capture a photo using the camera for use by the app, but also ensure that the photo is saved into the device's shared gallery.
I am using the TakePicture activity result contract, and passing it a Uri that I build using the MediaStore API. The code in my Activity looks like this:
private var takePictureUri: Uri? = null
val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) {
result: Boolean ->
val uri = takePictureUri
if(result && uri != null) {
// Do something with the captured image
}
}
fun takePicture() {
val collectionUri = if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
} else {
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
}
val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US)
.format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, timestamp)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
}
takePictureUri = contentResolver.insert(collectionUri, contentValues)
takePictureLauncher.launch(takePictureUri)
}
This all seems to work so far, which is great!
However, all the examples I could find of using the TakePicture activity supply a Uri using the FileProvider API, not the MediaStore API, so I am worried this may be a incorrect or poorly supported approach.
In particular, I am concerned about the fact that this approach requires me to specify a mime type before launching the TakePicture activity – how can I be sure the TakePicture activity will return a JPEG and not, say, a HEIF image?
Is there a more correct way to achieve my goal?