java.io.FileNotFoundException: 文件提供者
java.io.FileNotFoundException: fileprovider
我知道有很多关于 fileProvider 的帖子,但我似乎无法在那里找到我的问题的答案。
我使用以下意图拍摄图像:
private fun openCamera() {
currentFocus?.clearFocus()
val intent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
为了完成这项工作,我还有一个观察者:
fun observe(): Flowable<Picture> =
pictureSubject.onBackpressureLatest()
.map { uri ->
appContext.get()?.let {
val cursor = it.contentResolver.query(uri, null, null, null, "date_added DESC, _id DESC")
if (cursor != null) {
if (cursor.moveToNext()) {
val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
val filePath = cursor.getString(dataColumn)
val name = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
return@map Picture()
.apply {
this.name = cursor.getString(name)
this.path = filePath
}
}
cursor.close()
}
return@map Picture()
}
return@map Picture()
}
然后将这些图片添加到一个名为文件的对象中。
fun listenForGeneralPictures(observe: Flowable<Picture>?) {
observe?.apply {
generalPictureDisposable = concatMap {
if (it.name?.isNotEmpty() == true
&& it.path?.isNotEmpty() == true
&& file != null) {
it.categoryNr = Picture.CAT_GENERAL_PICTURES
file?.generalPictures?.add(it)
Log.d(it.name.toString(), "pictureAfter")
return@concatMap fileRepository.update(file!!)
} else {
return@concatMap Flowable.just(file)
}
}.subscribe({
cachedFile?.generalPictures = it!!.generalPictures
}, errorUtils::onError)
}
}
我正在使用它来获取路径并将图像设置为 Imageview:
override fun showPicture(path: String?) {
val pictureFile = File(path)
ivDraw?.setImageUri(FileProvider.getUriForFile(this, this.applicationContext.packageName + ".provider", pictureFile))
}
但是当我这样做时出现错误:
System.err: java.io.FileNotFoundException:
/external_path/DCIM/Camera/20180801_115654(1).jpg (No such file or
directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:146)
at java.io.FileInputStream.(FileInputStream.java:99)
at android.content.ContentResolver.openInputStream(ContentResolver.java:708)
at com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.rotateImageToTakenDirection(DrawImageView.kt:108)
at com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.setImageUri(DrawImageView.kt:54)
at com.insypro.inspector3.ui.picture.PictureViewActivity.showPicture(PictureViewActivity.kt:124)
at com.insypro.inspector3.ui.picture.PicturePresenter.processPicture(PicturePresenter.kt:69)
at com.insypro.inspector3.ui.picture.PicturePresenter.access$processPicture(PicturePresenter.kt:24)
at com.insypro.inspector3.ui.picture.PicturePresenter$loadDataPicture.accept(PicturePresenter.kt:51)
我还有一个 fileprovider 文件和清单中需要的所有内容:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
tools:replace="android:resource"/>
</provider>
和路径:
<paths>
<files-path name="files" path="." />
<cache-path name="cache" path="/"/>
<external-path name="external_path" path="." />
<external-files-path name="external_files" path="." />
I take images, using the following intent:
Intent
操作只是打开一个相机应用程序,这是数百个可能的应用程序之一。用户是否使用该相机应用拍照由用户决定。
To make this work, I also have an Observer
相机应用不需要通过任何 ContentProvider
提供其图像,例如 MediaStore
。
不需要 dataColumn
到 return 文件系统路径。
不需要 dataColumn
到 return 您具有读取权限的文件系统路径。
IOW,此代码在约 24,000 个 Android 设备型号和约 20 亿 Android 用户中将不可靠。
I'm using this, to get to the path and set the image to an Imageview
不要使用 setImageUri()
。 The documentation 特别反对。
这里不要使用FileProvider
。这是为了与其他应用程序共享内容,而不是供您自己的应用程序内部使用。此外,因为您不知道 dataColumn
将指向何处,所以您无法配置 FileProvider
来提供任意文件。
相反,将您的 "path" 传递给您最喜欢的图像加载库(例如 Glide、Picasso),它会尝试在后台线程上加载您的照片,然后用 ImageView
填充您的结果。
嗯,首先你需要了解 FileProvider 在哪里
是为了。它用于以安全的方式将本地文件共享给 其他 应用程序:https://developer.android.com/reference/android/support/v4/content/FileProvider
您仅在您的自己的应用程序中使用图像文件。因此根本不需要使用 FileProvider
。
要显示图像,请使用 BitmapFactory
,请注意 your_path
是图像的完整路径,未被 FileProvider
更改:
val bitmap = BitmapFactory.decodeFile(your_path);
ivDraw.setImageBitmap(bitmap);
我知道有很多关于 fileProvider 的帖子,但我似乎无法在那里找到我的问题的答案。
我使用以下意图拍摄图像:
private fun openCamera() {
currentFocus?.clearFocus()
val intent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}
}
为了完成这项工作,我还有一个观察者:
fun observe(): Flowable<Picture> =
pictureSubject.onBackpressureLatest()
.map { uri ->
appContext.get()?.let {
val cursor = it.contentResolver.query(uri, null, null, null, "date_added DESC, _id DESC")
if (cursor != null) {
if (cursor.moveToNext()) {
val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
val filePath = cursor.getString(dataColumn)
val name = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME)
return@map Picture()
.apply {
this.name = cursor.getString(name)
this.path = filePath
}
}
cursor.close()
}
return@map Picture()
}
return@map Picture()
}
然后将这些图片添加到一个名为文件的对象中。
fun listenForGeneralPictures(observe: Flowable<Picture>?) {
observe?.apply {
generalPictureDisposable = concatMap {
if (it.name?.isNotEmpty() == true
&& it.path?.isNotEmpty() == true
&& file != null) {
it.categoryNr = Picture.CAT_GENERAL_PICTURES
file?.generalPictures?.add(it)
Log.d(it.name.toString(), "pictureAfter")
return@concatMap fileRepository.update(file!!)
} else {
return@concatMap Flowable.just(file)
}
}.subscribe({
cachedFile?.generalPictures = it!!.generalPictures
}, errorUtils::onError)
}
}
我正在使用它来获取路径并将图像设置为 Imageview:
override fun showPicture(path: String?) {
val pictureFile = File(path)
ivDraw?.setImageUri(FileProvider.getUriForFile(this, this.applicationContext.packageName + ".provider", pictureFile))
}
但是当我这样做时出现错误:
System.err: java.io.FileNotFoundException: /external_path/DCIM/Camera/20180801_115654(1).jpg (No such file or directory) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.(FileInputStream.java:146) at java.io.FileInputStream.(FileInputStream.java:99) at android.content.ContentResolver.openInputStream(ContentResolver.java:708) at com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.rotateImageToTakenDirection(DrawImageView.kt:108) at com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.setImageUri(DrawImageView.kt:54) at com.insypro.inspector3.ui.picture.PictureViewActivity.showPicture(PictureViewActivity.kt:124) at com.insypro.inspector3.ui.picture.PicturePresenter.processPicture(PicturePresenter.kt:69) at com.insypro.inspector3.ui.picture.PicturePresenter.access$processPicture(PicturePresenter.kt:24) at com.insypro.inspector3.ui.picture.PicturePresenter$loadDataPicture.accept(PicturePresenter.kt:51)
我还有一个 fileprovider 文件和清单中需要的所有内容:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
tools:replace="android:resource"/>
</provider>
和路径:
<paths>
<files-path name="files" path="." />
<cache-path name="cache" path="/"/>
<external-path name="external_path" path="." />
<external-files-path name="external_files" path="." />
I take images, using the following intent:
Intent
操作只是打开一个相机应用程序,这是数百个可能的应用程序之一。用户是否使用该相机应用拍照由用户决定。
To make this work, I also have an Observer
相机应用不需要通过任何 ContentProvider
提供其图像,例如 MediaStore
。
不需要 dataColumn
到 return 文件系统路径。
不需要 dataColumn
到 return 您具有读取权限的文件系统路径。
IOW,此代码在约 24,000 个 Android 设备型号和约 20 亿 Android 用户中将不可靠。
I'm using this, to get to the path and set the image to an Imageview
不要使用 setImageUri()
。 The documentation 特别反对。
这里不要使用FileProvider
。这是为了与其他应用程序共享内容,而不是供您自己的应用程序内部使用。此外,因为您不知道 dataColumn
将指向何处,所以您无法配置 FileProvider
来提供任意文件。
相反,将您的 "path" 传递给您最喜欢的图像加载库(例如 Glide、Picasso),它会尝试在后台线程上加载您的照片,然后用 ImageView
填充您的结果。
嗯,首先你需要了解 FileProvider 在哪里 是为了。它用于以安全的方式将本地文件共享给 其他 应用程序:https://developer.android.com/reference/android/support/v4/content/FileProvider
您仅在您的自己的应用程序中使用图像文件。因此根本不需要使用 FileProvider
。
要显示图像,请使用 BitmapFactory
,请注意 your_path
是图像的完整路径,未被 FileProvider
更改:
val bitmap = BitmapFactory.decodeFile(your_path);
ivDraw.setImageBitmap(bitmap);