I have the following function to select an image and display it in an ImageView (only relevant code):
Start gallery picker:
 fun selectPic(view: View) {
    val intent = Intent(Intent.ACTION_PICK);
    intent.type = "image/*";
    startActivityForResult(intent, 1000);
}
Get selected image from gallery picker:
 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == Activity.RESULT_OK && requestCode == 1000) {
            println("DATA " + data?.data)
            // SET PATH TO GLOBAL VARIABLE
            uri_path = data?.data;
            findViewById<ImageView>(R.id.selected_image).setImageURI(data?.data);
        }
}
Then I use this piece of code to retrieve the image again so I can upload the file to a server:
...
 val file: File = File(getRealPathFromURI(fileUri));
...
getRealPathFromUri()
 fun getRealPathFromURI(uri: Uri?): String? {
        val cursor: Cursor? = contentResolver.query(uri!!, null, null, null, null)
        if (cursor == null) {
            return null;
        }
        cursor.moveToFirst()
        val idx: Int = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
        return cursor.getString(idx)
    }
uploadFile
private fun uploadFile(fileUri: Uri) {
        // create upload service client
        val service: FileUploadService =
            ServiceGenerator.createService(FileUploadService::class.java)
        // uri_path IS THE GLOBAL VARIABLE WITH VALUE data?.data
        val file: File = File(uri_path.toString());
        // create RequestBody instance from file
        val requestFile = RequestBody.create(
            MediaType.parse(contentResolver.getType(fileUri)),
            file
        )
        // MultipartBody.Part is used to send also the actual file name
        val body =
            MultipartBody.Part.createFormData("file", file.name, requestFile)
        // add another part within the multipart request
        val descriptionString = "hello, this is description speaking"
        val description = RequestBody.create(
            MultipartBody.FORM, descriptionString
        )
        // finally, execute the request
        val call: Call<ResponseBody?>? = service.upload(description, body)
        if (call != null) {
            call.enqueue(object : Callback<ResponseBody?> {
                override fun onResponse(
                        call: Call<ResponseBody?>?,
                        response: Response<ResponseBody?>?
                ) {
                    Log.v("Upload", "success")
                    println("RESPONSE " + response);
                }
                override fun onFailure(call: Call<ResponseBody?>?, t: Throwable) {
                    t.message?.let { Log.e("Upload error:", it) }
                }
            })
        }
    }
Relevant parts of my AndroidManifext.xml:
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="ANDROID.PERMISSION.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="ANDROID.PERMISSION.WRITE_EXTERNAL_STORAGE"/>
    <application
        ...
        android:usesCleartextTraffic="true"
        android:requestLegacyExternalStorage="true">
        ...
The weird issue is that it works for some files. Example of file that works:
I/System.out: URI content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F64/ORIGINAL/NONE/image%2Fjpeg/1462875550
This file works perfectly and uploads!
But this file gives an error:
E/Upload error:: /storage/emulated/0/Pictures/IMG_20210518_151857.jpg: open failed: EACCES (Permission denied)
Error: open failed: EACCES (Permission denied).
Why is the permission denied for this file? I do have the correct requirements in my AndroidManifext.xml?