0

In my application I want show FilePicker to user and can choose file from it.
After choose file by user I should convert it to file!
I write below codes, but after select file from user show me force close error and application crashed!
My activity codes:

class MyActivity : BaseActivity() {

private var uploadFile: File? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        _binding = ActivityAddMaangramBinding.inflate(layoutInflater)
        setContentView(binding.root)

        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 ->
                        Log.e("UriLog",itUri.toString())
                        uploadFile = getRealPathFromURI(this, itUri)?.let { str -> File(str) }!!
                    }
                }
            }
        }
    }

    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, "Select the file")
        resultIntent.launch(intent)
    }
}

With this code I convert URI to String:

@SuppressLint("Range")
fun getRealPathFromURI(context: Context, contentURI: Uri): String? {
    var result = contentURI.path
    val cursor = context.contentResolver.query(contentURI, null, null, null, null)
    if (cursor == null) {
        result = contentURI.path
    } else {
        if (cursor.moveToFirst()) {
            result =
                cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA))
        }
        cursor.close()
    }
    return result
}

But show me below error in logcat:

java.lang.RuntimeException: Unable to resume activity {com.myapp/com.myapp.MyActivity}: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3430)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3470)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6121)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
 Caused by: java.lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.
    at android.database.CursorWindow.nativeGetString(Native Method)
    at android.database.CursorWindow.getString(CursorWindow.java:438)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51)
    at android.database.CursorWrapper.getString(CursorWrapper.java:137)
    at com.myapp.utils.ExtensionsKt.getRealPathFromURI(Extensions.kt:207)
    at com.myapp.MyActivity.onCreate$lambda-10(MyActivity.kt:95)
    at com.myapp.MyActivity.$r8$lambda$NQEpsBx9Gb6p_-32st3oxAwf-VU(MyActivity.kt)
    at com.myapp.MyActivity$$ExternalSyntheticLambda4.onActivityResult(D8$$SyntheticClass)
    at androidx.activity.result.ActivityResultRegistry$1.onStateChanged(ActivityResultRegistry.java:149)
    at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:360)
    at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:271)
    at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:313)
    at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:151)
    at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:134)
    at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:68)
    at androidx.lifecycle.ReportFragment.dispatch(ReportFragment.java:144)
    at androidx.lifecycle.ReportFragment.onStart(ReportFragment.java:109)
    at android.app.Fragment.performStart(Fragment.java:2379)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1027)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1171)
    at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1153)
    at android.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2044)
    at android.app.FragmentController.dispatchStart(FragmentController.java:187)
    at android.app.Activity.performStart(Activity.java:6783)
    at android.app.Activity.performRestart(Activity.java:6851)
    at android.app.Activity.performResume(Activity.java:6856)
    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3407)
    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3470) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:154) 
    at android.app.ActivityThread.main(ActivityThread.java:6121) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779) 

Show me error fir this line : uploadFile = getRealPathFromURI(this, itUri)?.let { str -> File(str) }!!

I write Log code for see uri path, show me this path in logcat:

E/UriLog: content://com.android.providers.media.documents/document/image%3A28

How can I fix this problem and convert URI to String?

Dr.KeyOk
  • 608
  • 1
  • 6
  • 13
  • A `Uri` is not a file. Use `ContentResolver` and `openInputStream()` or `openOutputStream()` to work with the content identified by the `Uri`. – CommonsWare Nov 19 '22 at 13:43
  • @CommonsWare , Thanks <3 Can you send to me code for this? – Dr.KeyOk Nov 19 '22 at 13:46
  • I do not know what "code for this" you are seeking. Can you please explain in detail what it is you intend to do with the content? – CommonsWare Nov 19 '22 at 13:49
  • @CommonsWare I write below code : `Log.e("UriLog", contentResolver.openInputStream(itUri).toString())` but not show me file path. I want get file path and upload to server. please help me . Thanks – Dr.KeyOk Nov 19 '22 at 13:59
  • "but not show me file path" -- there is no file path, because the user does not have to choose a file on the filesystem. "I want get file path and upload to server" -- you do not need a filesystem path to upload content to a server. [This duplicate](https://stackoverflow.com/questions/56308559/create-a-file-from-a-photo-uri-on-android) covers that, pointing to [this blog post](https://commonsware.com/blog/2020/07/05/multipart-upload-okttp-uri.html) and other resources for uploading to a server using a `Uri`. – CommonsWare Nov 19 '22 at 14:19

0 Answers0