1

I am trying to implement taking a photo from a camera on a project that targets Android Q. From what I have found, I have implemented this:

val mediaFile = mediaManager.createImageFile() // creates a file to store the image and returns Uri
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.apply {
  addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
  type = MIME_TYPE_IMAGE //"image/*"
  intent.putExtra(MediaStore.EXTRA_OUTPUT, mediaFile)
}
startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO)

createImageFile:

override fun createImageFile(): Uri? {
    return createFile(mimeType = MIME_IMAGE_JPG, isImage = true)
}

private fun createFile(mimeType: String, isImage: Boolean): Uri? {
val mediaFileName = createTempName()

val path = if (isImage) {
  Environment.DIRECTORY_PICTURES
} else {
  Environment.DIRECTORY_MOVIES
}

val contentValues = ContentValues().apply {
  put(MediaStore.MediaColumns.DISPLAY_NAME, mediaFileName)
  put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
  put(MediaStore.MediaColumns.RELATIVE_PATH, path)
}
val resolver = context.contentResolver
val contentUri = if (isImage) {
  MediaStore.Images.Media.EXTERNAL_CONTENT_URI
} else {
  MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
return resolver.insert(contentUri, contentValues)
}

However, I get android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.media.action.IMAGE_CAPTURE typ=image/* flg=0x3 clip={text/uri-list U:content://media/external/images/media/109855} (has extras) }

I searched for hours and did everything as stated, but still no luck. Funny enough, createImageFile() returns null Samsung Galaxy S8 (God, I hate Samsungs, it is always some special case for those). What am I doing wrong here?

Sermilion
  • 1,920
  • 3
  • 35
  • 54
  • Give a look [here.](https://stackoverflow.com/questions/49435522/error-no-activity-found-to-handle-intent-act-android-media-action-image-capture) You will find how to solve this problem. – gcantoni Apr 18 '20 at 14:42
  • @gcantoni thanks for the reply, but that solution uses `Environment.getExternalStorageDirectory()` which is deprecated on Android Q. – Sermilion Apr 18 '20 at 14:44
  • Deprecated is not synonymous of junk, it is always working code! give it a try – gcantoni Apr 18 '20 at 14:46
  • 1
    First, remove `type = MIME_TYPE_IMAGE`. Do not provide a MIME type on an `ACTION_IMAGE_CAPTURE` request. Second, get rid of `RELATIVE_PATH`, as that is unnecessary given how you are using it. – CommonsWare Apr 18 '20 at 14:49
  • @CommonsWare well, this worked. Setting MIME type was the issue. Much appreciated! – Sermilion Apr 18 '20 at 14:56

1 Answers1

1

The MIME type on an Intent forms part of the criteria for determining what activities have an <intent-filter> that matches the Intent. Adding a MIME type on an Intent, where that MIME type is unexpected, will lead to problems like you are seeing.

The ACTION_IMAGE_CAPTURE documentation says nothing about supplying a MIME type on the request. As a result, camera apps with ACTION_IMAGE_CAPTURE <intent-filter> structures will not be advertising that they support any particular MIME types. And, as a result, when Android tries finding a matching activity for your Intent, it comes up empty.

So, remove the MIME type to clear up the ActivityNotFoundException.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491