嗨伙计们,我得到了一个错误,像下面的一个当试图从厨房上传图像:
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{efed650 15275:app.fadlyproject.com/u0a158} (pid=15275, uid=10158) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
错误来自这行代码:
val parcelFileDescriptor =
contentResolver.openFileDescriptor(selectedImageUri!!, "r", null) ?: return
我使用的是第三方库,即DrJacky和Retrofit 2。我在清单中添加了一些必要的内容,如下所示:
依赖关系:
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.github.Drjacky:ImagePicker:2.3.19'
清单:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view = findViewById(R.id.image_view)
button_upload = findViewById(R.id.button_upload)
image_view!!.setOnClickListener {
openImageChooser()
}
button_upload!!.setOnClickListener {
uploadImage()
}
}
private val profileLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val uri = it.data?.data!!
selectedImageUri = uri
image_view!!.setImageURI(selectedImageUri)
} else parseError(it)
}
private fun openImageChooser() {
ImagePicker.with(this)
.provider(ImageProvider.BOTH)
.setDismissListener {
Log.d("ImagePicker", "onDismiss");
}
.createIntentFromDialog { profileLauncher.launch(it) }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_CODE_PICK_IMAGE -> {
selectedImageUri = data?.data
image_view!!.setImageURI(selectedImageUri)
}
}
}
}
private fun uploadImage() {
if (selectedImageUri == null) {
layout_root!!.snackbar("Select an Image First")
return
}
val parcelFileDescriptor =
contentResolver.openFileDescriptor(selectedImageUri!!, "r", null) ?: return
val inputStream = FileInputStream(parcelFileDescriptor.fileDescriptor)
val file = File(cacheDir, contentResolver.getFileName(selectedImageUri!!))
val outputStream = FileOutputStream(file)
inputStream.copyTo(outputStream)
progress_bar!!.progress = 0
val body = UploadRequestBody(file, "image", this)
MyAPI().uploadImage(
MultipartBody.Part.createFormData(
"file",
file.name,
body
),
RequestBody.create(MediaType.parse("multipart/form-data"), "json")
).enqueue(object : Callback<UploadResponse> {
override fun onFailure(call: Call<UploadResponse>, t: Throwable) {
layout_root!!.snackbar(t.message!!)
progress_bar!!.progress = 0
}
override fun onResponse(
call: Call<UploadResponse>,
response: Response<UploadResponse>
) {
response.body()?.let {
layout_root!!.snackbar(it.message)
progress_bar!!.progress = 100
classes!!.text = it.data.classes
layout!!.visibility = View.VISIBLE
Glide.with(this@MainActivity).load("http://167.172.72.26:1337/"+ it.data.image_after_preprocessing).into(
image_view!!
)
}
}
})
}
override fun onProgressUpdate(percentage: Int) {
progress_bar!!.progress = percentage
}
companion object {
const val REQUEST_CODE_PICK_IMAGE = 101
}
2条答案
按热度按时间nnvyjq4y1#
这个答案虽然迟了,但可能对其他人有所帮助。
我只是像这样添加了.crop()。
我注意到这个错误只在使用图库时存在,而添加.crop()是唯一的解决方案。
idv4meu82#
如果您不使用裁剪选项,您只需添加:
https://developer.android.com/training/data-storage/shared/photopicker#persist-media-file-access
我会在下次更新时将
ACTION_GET_CONTENT
更改为ACTION_OPEN_DOCUMENT
。[And如果我能找到一种兼顾两个方面方法(裁剪并让开发人员使用或不使用
takePersistableUriPermission
,我将再次更新。)