如何在Android 11中使用文件选择器



在我的应用程序中,我希望用户可以打开文件选择器并选择文件。
我写了下面的代码,但点击上传后显示错误和应用程序崩溃!
android 11一切都好,没有任何问题!
我在Activity中写了下面的代码:

class AddMaangramActivity : BaseActivity() {
private lateinit var requestBody: RequestBody
private val multiPart by lazy {
MultipartBody.Builder().setType(MultipartBody.FORM).addFormDataPart("_method", "post")
}
private lateinit var resultIntent: ActivityResultLauncher<Intent>
private var uploadFile: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityAddMaangramBinding.inflate(layoutInflater)
setContentView(binding.root)
//Open file picker
item2ImgLay.setOnClickListener { openFilePicker() }
//Activity result
resultIntent = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data = result.data
data?.let {
val uri = it.data
uri?.let { itUri ->
binding.coverImg.load(itUri)
uploadFile = File(getRealPathFromURIWithProvider(this, itUri))
}
}
}
}
//Upload
uploadBtn.setOnClickListener {
//File
val fileName = URLEncoder.encode(uploadFile?.absolutePath, "UTF-8")
val reqFile = uploadFile?.asRequestBody("multipart/form-data".toMediaTypeOrNull())
multiPart.addFormDataPart("file", fileName, reqFile!!)
val filePart = MultipartBody.Part.createFormData("file", fileName, reqFile)
body.file = filePart
//Submit
requestBody = multiPart.build()
}
}
private fun openFilePicker() {
var intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "*/*"
val type: Array<String> = arrayOf("image/*", "video/*")
intent.putExtra(Intent.EXTRA_MIME_TYPES, type)
intent = Intent.createChooser(intent, "Choose file")
resultIntent.launch(intent)
}
}

错误信息:

java.io.FileNotFoundException: : open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:492)
at java.io.FileInputStream.<init>(FileInputStream.java:160)
at okio.Okio__JvmOkioKt.source(JvmOkio.kt:182)
at okio.Okio.source(Unknown Source:1)
at okhttp3.RequestBody$Companion$asRequestBody$1.writeTo(RequestBody.kt:167)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.kt:157)
at okhttp3.MultipartBody.writeTo(MultipartBody.kt:93)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:202)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7b44291, Dispatchers.IO]
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7542)
at libcore.io.IoBridge.open(IoBridge.java:478)

另外,我将这行android:requestLegacyExternalStorage="true"添加到manifest应用程序在标签!再次显示错误

我该如何修复它?

你使用ACTION_OPEN_DOCUMENT让用户选择一个文件。

您不需要任何许可或请求任何类型的遗产。

你在责备文件拾取器。但是ACTION_OPEN_DOCUMENT给了你一个很好的uri。

麻烦只出现在uri:uploadFile = File(getRealPathFromURIWithProvider(this的地方。

Awfull。不要做这种下流的事。使用uri直接上传所选文件。

也与作用域存储无关。

最新更新