-1

I need to get the file path from my onActivityResult Uri in Kotlin. When I google for that I get a ton of different ways on how to do it, most of them are not working and a lot seem uneccessary complex, some of them solutions are even 8 years old. I also found some librarys like PickIt and Simplestorage.

What is currently the best practice (or one of the best practices) to get a file path from Uri? I'm building a Sound Editor and I need the real file path of the selected Sound File for that.

Storing the sound file as a temp file in my local storage would also be a solution for me, whats the best practice there?

P.S I'm also using Jetpack Compose if that matters

HavanaSun
  • 446
  • 3
  • 12
  • 39
  • I am using this solution from last one year for several projects - https://gist.github.com/tatocaster/32aad15f6e0c50311626 – Sandesh Khutal Apr 25 '22 at 09:23
  • `need to get the file path from my onActivityResult Uri` No. You will not need that as you can use the uri directly. First tell why you think you need a path where you have a nice uri that serves all. – blackapps Apr 25 '22 at 09:25
  • @blackapps when I try to create a File form the Uri I get the following error: *Uri lacks 'file' scheme: content://com.android.providers.media.documents/document/audio%3A14883* – HavanaSun Apr 25 '22 at 09:38
  • Then you do it clearly wrong. But.. you do not need to create a file as the file is already there. What you could do though is make a copy. But why would you need a copy. You can directly read the file from the uri, edit it and write it back to that uri. If you dont want to overwrite original file you could create another file. Only needed if the file got indeed edited. – blackapps Apr 25 '22 at 10:23
  • @blackapps How can I upload and image to via Retrofit when I only have the Uri? – HavanaSun May 19 '22 at 13:49

1 Answers1

0

Use MediaStore for the latest versions of Android, that's the recommended practice.

val projection = arrayOf(media-database-columns-to-retrieve)
val selection = sql-where-clause-with-placeholder-variables
val selectionArgs = values-of-placeholder-variables
val sortOrder = sql-order-by-clause

applicationContext.contentResolver.query(
    MediaStore.media-type.Media.EXTERNAL_CONTENT_URI,
    projection,
    selection,
    selectionArgs,
    sortOrder
)?.use { cursor ->
    while (cursor.moveToNext()) {
        // Use an ID column from the projection to get
        // a URI representing the media item itself.
    }
}

This is the basic structure of the API usage, you an read full details here.

Basically, you create a Directory in one of the default Android folders (in your case, it may be the 'Music' Directory), and then you read and write to that specific directory which is designated to your app.

Columns have default values, like name, thumbnail etc. You can get full URIs as well, there are a couple of methods available for that within the API, I think. You can read files using FileDescriptors like so

// Open a specific media item using ParcelFileDescriptor.
val resolver = applicationContext.contentResolver

// "rw" for read-and-write;
// "rwt" for truncating or overwriting existing file contents.
val readOnlyMode = "r"
resolver.openFileDescriptor(content-uri, readOnlyMode).use { pfd ->
    // Perform operations on "pfd".
}

Maybe have a look here - How to get the Uri from MediaStore via file path?

Richard Onslow Roper
  • 5,477
  • 2
  • 11
  • 42