java.io.FileNotFoundException:fileprovider

时间:2018-08-01 12:27:30

标签: android kotlin android-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(没有此类文件或   目录)               在java.io.FileInputStream.open(本机方法)               在java.io.FileInputStream。(FileInputStream.java:146)               在java.io.FileInputStream(FileInputStream.java:99)               在android.content.ContentResolver.openInputStream(ContentResolver.java:708)               在com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.rotateImageToTakenDirection(DrawImageView.kt:108)               在com.insypro.inspector3.ui.custom.picturedraw.DrawImageView.setImageUri(DrawImageView.kt:54)               在com.insypro.inspector3.ui.picture.PictureViewActivity.showPicture(PictureViewActivity.kt:124)               在com.insypro.inspector3.ui.picture.PicturePresenter.processPicture(PicturePresenter.kt:69)               在com.insypro.inspector3.ui.picture.PicturePresenter.access $ processPicture(PicturePresenter.kt:24)               在com.insypro.inspector3.ui.picture.PicturePresenter $ loadDataPicture $ 1.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="." />

2 个答案:

答案 0 :(得分:1)

  

我使用以下意图拍照:

Intent操作仅打开一个相机应用程序,这是数百种可能的应用程序之一。用户是否使用该相机应用程序拍照取决于用户。

  

要完成这项工作,我还有一个观察员

相机应用程序不需要通过任何ContentProvider(例如MediaStore)获得其图像。

dataColumn不需要返回文件系统路径。

dataColumn不需要返回您具有读取访问权限的文件系统路径。

IOW,此代码在约24,000个Android设备型号和约20亿Android用户中将不可靠。

  

我正在使用它来获取路径并将图像设置为Imageview

请勿使用setImageUri()The documentation特别建议不要这样做。

请勿在此处使用FileProvider。那是为了与其他应用程序共享内容,而不是供您自己的应用程序内部使用。此外,由于您不知道dataColumn指向何处,因此无法配置FileProvider来提供任意文件。

相反,将您的“路径”传递到您喜欢的图像加载库(例如Glide,毕加索),该库可以尝试将照片加载到后台线程上,然后将结果填充到ImageView中。 / p>

答案 1 :(得分:1)

好吧,首先,您需要了解 FileProvider 的位置  是为了。它用于以安全的方式与其他应用共享本地文件:https://developer.android.com/reference/android/support/v4/content/FileProvider

您仅在 own 应用程序中使用图像文件。因此,根本不需要使用FileProvider

要显示图像,请使用BitmapFactory,请注意your_path是图像的完整路径,不会被FileProvider更改:

val bitmap = BitmapFactory.decodeFile(your_path);
ivDraw.setImageBitmap(bitmap);