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

p4tfgftt  于 2022-12-02  发布在  Android
关注(0)|答案(1)|浏览(306)

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

我在活动中编写以下代码:

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"添加到application标记中的manifest!再次显示错误
我该如何修复它?

fhity93d

fhity93d1#

您可以使用ACTION_OPEN_DOCUMENT让使用者选择档案。
为此,您不需要任何许可或请求任何形式的遗产。
你在责怪filepicker。但是ACTION_OPEN_DOCUMENT给了你一个很好的uri。这一切都正常。
麻烦只从哪里开始,在哪里用uri来乱转:uploadFile = File(getRealPathFromURIWithProvider(this .
太糟糕了。不要做这种下流的事情。直接用uri上传选择的文件。
也与作用域存储无关。

相关问题