Android:尝试获取保存的图像 URI 时没有内容提供者
Android: No content provider when trying to get saved Image URI
我有一个片段应该:打开相机,显示拍摄的照片,保存 URI 路径 (sqlite) 并再次显示该照片,如果我 return 到片段(获取保存的 URI 路径)
我的问题 是当我尝试将保存的 URI 路径转换为位图时。 此错误发生于:
FileNotFoundException: No content provider:
/external_files/Pictures/JPEG_20201001_234640_3080292023640638214.jpg (No such file or directory)
我的片段:
class TakePictureFragment : Fragment() {
private var photoURI: Uri? = null
private var imageView: ImageView? = null
private val itemId by lazy {
arguments?.getLong("ITEM_ID")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.content_take_picture,container,false)
imageView = view.findViewById(R.id.view_show_photo)
val button: Button = view.findViewById(R.id.open_camera)
button.setOnClickListener {
openCamera()
}
return view
}
override fun onResume() {
super.onResume()
val photo = PhotoDAO.get(itemId)
if(photo != null) {
photoURI = Uri.parse(photo.photoURI)
showPhoto()
}
}
private fun openCamera() {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoFile: File? = null
try {
photoFile = createImageFile()
} catch (ex: IOException) {
Log.i("ERROR", "IOException")
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
photoFile)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(cameraIntent, 1)
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
return File.createTempFile(imageFileName, ".jpg", storageDir)
// The shame problem happens if I return: return File(storageDir, "$imageFileName.jpg")
}
private fun showPhoto() {
val imageBitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoURI)
imageView?.setImageBitmap(imageBitmap)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == RESULT_OK) {
showPhoto()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.actionNext) {
PhotoDAO.save(itemId, photoURI?.path)
// Go to next Activity / Fragment
return true
}
return false
}
}
PS:URI 路径字符串正在保存并从“PhotoDAO”正确获取
PS2:如果我使用 Uri.fromFile(File(photo.photoURI))
而不是 Uri.parse(photo.photoURI)
,错误只是“没有这样的文件或目录”
它是这样工作的:
class TakePictureFragment : Fragment() {
private var photoURI: Uri? = null
private var photoPath = ""
private var imageView: ImageView? = null
private val itemId by lazy {
arguments?.getLong("ITEM_ID")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.content_take_picture,container,false)
imageView = view.findViewById(R.id.view_show_photo)
val button: Button = view.findViewById(R.id.open_camera)
button.setOnClickListener {
openCamera()
}
return view
}
override fun onResume() {
super.onResume()
val photo = PhotoDAO.get(itemId)
if(photo != null) {
photo_description.setText(photo.description)
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
File(photo.path))
showPhoto()
}
}
private fun openCamera() {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoFile: File? = null
try {
photoFile = createImageFile()
} catch (ex: IOException) {
Log.i("ERROR", "IOException")
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
photoFile)
photoPath = photoFile.absolutePath
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(cameraIntent, 1)
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
return File(storageDir, "$imageFileName.jpg")
}
private fun showPhoto() {
val imageBitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoURI)
imageView?.setImageBitmap(imageBitmap)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == RESULT_OK) {
showPhoto()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.actionNext) {
PhotoDAO.save(itemId, photoPath)
// Go to next Activity / Fragment
return true
}
return false
}
}
感谢@blackapps 在评论中提供“getAbsolutePath”提示。
我有一个片段应该:打开相机,显示拍摄的照片,保存 URI 路径 (sqlite) 并再次显示该照片,如果我 return 到片段(获取保存的 URI 路径)
我的问题 是当我尝试将保存的 URI 路径转换为位图时。 此错误发生于:
FileNotFoundException: No content provider:
/external_files/Pictures/JPEG_20201001_234640_3080292023640638214.jpg (No such file or directory)
我的片段:
class TakePictureFragment : Fragment() {
private var photoURI: Uri? = null
private var imageView: ImageView? = null
private val itemId by lazy {
arguments?.getLong("ITEM_ID")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.content_take_picture,container,false)
imageView = view.findViewById(R.id.view_show_photo)
val button: Button = view.findViewById(R.id.open_camera)
button.setOnClickListener {
openCamera()
}
return view
}
override fun onResume() {
super.onResume()
val photo = PhotoDAO.get(itemId)
if(photo != null) {
photoURI = Uri.parse(photo.photoURI)
showPhoto()
}
}
private fun openCamera() {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoFile: File? = null
try {
photoFile = createImageFile()
} catch (ex: IOException) {
Log.i("ERROR", "IOException")
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
photoFile)
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(cameraIntent, 1)
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
return File.createTempFile(imageFileName, ".jpg", storageDir)
// The shame problem happens if I return: return File(storageDir, "$imageFileName.jpg")
}
private fun showPhoto() {
val imageBitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoURI)
imageView?.setImageBitmap(imageBitmap)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == RESULT_OK) {
showPhoto()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.actionNext) {
PhotoDAO.save(itemId, photoURI?.path)
// Go to next Activity / Fragment
return true
}
return false
}
}
PS:URI 路径字符串正在保存并从“PhotoDAO”正确获取
PS2:如果我使用 Uri.fromFile(File(photo.photoURI))
而不是 Uri.parse(photo.photoURI)
,错误只是“没有这样的文件或目录”
它是这样工作的:
class TakePictureFragment : Fragment() {
private var photoURI: Uri? = null
private var photoPath = ""
private var imageView: ImageView? = null
private val itemId by lazy {
arguments?.getLong("ITEM_ID")
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.content_take_picture,container,false)
imageView = view.findViewById(R.id.view_show_photo)
val button: Button = view.findViewById(R.id.open_camera)
button.setOnClickListener {
openCamera()
}
return view
}
override fun onResume() {
super.onResume()
val photo = PhotoDAO.get(itemId)
if(photo != null) {
photo_description.setText(photo.description)
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
File(photo.path))
showPhoto()
}
}
private fun openCamera() {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
var photoFile: File? = null
try {
photoFile = createImageFile()
} catch (ex: IOException) {
Log.i("ERROR", "IOException")
}
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(context,
context.applicationContext.packageName + ".provider",
photoFile)
photoPath = photoFile.absolutePath
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(cameraIntent, 1)
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val imageFileName = "JPEG_" + timeStamp + "_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
return File(storageDir, "$imageFileName.jpg")
}
private fun showPhoto() {
val imageBitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, photoURI)
imageView?.setImageBitmap(imageBitmap)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == RESULT_OK) {
showPhoto()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.actionNext) {
PhotoDAO.save(itemId, photoPath)
// Go to next Activity / Fragment
return true
}
return false
}
}
感谢@blackapps 在评论中提供“getAbsolutePath”提示。