Как безопасно сохранить файл при использовании провайдера контента MediaStore и EXTRA_OUTPUT намерения камеры - PullRequest
0 голосов
/ 09 ноября 2019

Я хочу сделать снимок, используя намерение MediaStore.ACTION_IMAGE_CAPTURE, а затем сохранить его по определенному пути с помощью contentresolver.insert() и передать URI с помощью EXTRA_OUTPUT. Вот как я это делаю (с разрешения WRITE_EXTERNAL_STORAGE предоставлено):

val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
val imageData = ContentValues()
val imageTableUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
imageData.put(MediaStore.MediaColumns.DISPLAY_NAME, "${filename}.jpg")
imageData.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
imageData.put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/MyPath")
val imageUri = contentResolver.insert(imageTableUri, imageData)
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
intent.also { takePictureIntent ->
    takePictureIntent.resolveActivity(packageManager).also {
        startActivityForResult(takePictureIntent, takePictureRequestCode)
    }
}

Этот код будет работать. Но если я:

  1. Отмените намерение камеры с помощью кнопки Назад или
  2. Переключитесь на другие приложения, оставаясь в камере, вызванной моей деятельностью

приложение Photo покажет неполное фото, информация которого не может быть отображена: неполное фото в приложении Photo (обозначено красным квадратом)

Кроме того, то же самое DISPLAY_NAME вызовет contentResolver.insert() для возврата null, даже если я вручную удалил эту неполную фотографию (с помощью приложения «Фото» или «Диспетчер файлов»), а также не могу найти файл по contentResolver.query() с предложением выбрать это имя файла.

В первом случае я могу вызвать contentResolver.delete() в onActivityResult() методе моей деятельности, поскольку URI может быть сохранен. Но есть ли способ справиться со вторым случаем (который иногда может вызвать непосредственное завершение приложения)? Или я неправильно использовал один из методов ContentResolver или камеры?

...