Issue
I am developing a camera app and would like to implement the feature that allows the app to return an image to another app which called the IMAGE_CAPTURE_INTENT.
val pictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
I have found a lot of information on the internet on how to request another camera app to capture an image and return it, but I did not find any information on how to deal with it the other way round, like in the case my app would need to accept the intent and return the image to another app. I hope this makes sense.
Would greatly appreciate any help.
Solution
After research and experimenting, I have partially solved the problem. If I understood it correctly, there are two ways the IMAGE_CAPTURE_INTENT works: If the ACTION_IMAGE_CAPTURE Intent contains EXTRA_OUTPUT, which is a Uri, you can save your taken image using this Uri to return an image. If there is no EXTRA_OUTPUT, the Intent for use with setResult() should contain a thumbnail-sized Bitmap in the _data extra. (Thanks @CommonsWare for the info!) I have only implemented the first option with the Uri, as I am still unsure how to do it with the thumbnail (most apps provide an Uri with their intent anyway).
The approach I took to return an image (only with Uri):
- Detect if the activity has been started due to an intent. Add the code below ideally in onResume, so the code checks for an intent every time the app is opened:
//check if activity was opened due to an intent
val isImageCaptureIntent = this.intent.action == MediaStore.ACTION_IMAGE_CAPTURE
if(isImageCaptureIntent) {
//retrieve the uri
val output = intent.extras?.get(MediaStore.EXTRA_OUTPUT)
//check if it is an Uri and not null
if (output != null && output is Uri) {
val uriImageCaptureIntent = output
isImageCaptureIntentWithUri = true
//an Uri is provided
}else{
isImageCaptureIntentWithUri = false
//an Uri is not provided, return a thumbnail-sized bitmap.
//I have not included a solution for this case!
}
}
- After the picture has been taken, save the image:
val imageOutStream: OutputStream
val contentResolver = context.contentResolver
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
//use this approach to save the image with Android 10+ due to scoped storage
val mimeType = "image/jpeg"
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
put(MediaStore.Images.Media.MIME_TYPE, mimeType)
put(MediaStore.Images.Media.RELATIVE_PATH, directory)
}
contentResolver.run {
imageOutStream = openOutputStream(uriImageCaptureIntent) ?: return
}
}else{
//use this code for Android 9 and below
imageOutStream = context.contentResolver.openOutputStream(uriImageCaptureIntent)!!
}
try {
//bitmap equals the captured image
bitmap.compress(Bitmap.CompressFormat.JPEG, photoCompression, imageOutStream)
imageOutStream.flush()
} catch (e: java.lang.Exception) {
e.printStackTrace()
} finally {
imageOutStream.close()
}
- After storing the image, set result to OK and close the app:
requireActivity().setResult(Activity.RESULT_OK, requireActivity().intent)
requireActivity().finish()
Update: Starting from Android 11, Android will no longer allow any third-party apps to capture an image via IMAGE_CAPTURE_INTENT. While the above code should work fine for Android 10 and below, starting form Android 11, no third-party apps will show up in the camera selection interface, when selecting an app to execute the capture intent.
Answered By - MichaelK
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.