2

After a button click, I want to create an Intent for browsing files and selecting a directory. Then I want to store a path for this directory in shared preferences. Later I want to use this path as an argument for a File object, so I can, for example, get a parent directory of a directory I picked, or list all its files. The problem is, I am getting this path from Intent:

content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata

I read here link and tried to convert content Uri to File Uri using cursor, but i am getting this error:

java.lang.UnsupportedOperationException: Unsupported Uri content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata

Is it because of characters before "Android" and "data" folder ? It always fails when trying to create a cursor.

Here is a simple example of what I want to achieve. I did not include a code for converting Content Uri to File Uri. I tried almost every code for this what I found, but with no result.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    button.setOnClickListener {
        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
        startActivityForResult(intent, SELECT_DIRECTORY)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == SELECT_DIRECTORY) {
            val path = data?.data
            // convert content Uri to File Uri ?
            // store path in shared preferences...
            // later use it in File File(storedPath)
        }
    }
}
tomas
  • 376
  • 1
  • 5
  • 17
  • "I want to create an Intent for browsing files and selecting a directory" -- Android does not have an `Intent` for this. "The problem is, I am getting this path from Intent" -- that is not a path. That is a string representation of a `Uri`. Specifically, it is a `Uri` pointing to a document tree, a `Uri` that you obtained via the Storage Access Framework. That document tree can be *anywhere* (e.g., Google Drive, Windows file server); it does not have to represent a directory on an on-device filesystem that you can access. – CommonsWare Mar 19 '18 at 10:28
  • "I want to store it in shared preferences" -- be sure to [call `takePersistableUriPermission()`](https://developer.android.com/reference/android/content/ContentResolver.html#takePersistableUriPermission(android.net.Uri,%20int)). Or, if you insist that you are only willing to work with filesystem directories, stop using `ACTION_OPEN_DOCUMENT_TREE` and [use a directory chooser library](https://android-arsenal.com/tag/35). – CommonsWare Mar 19 '18 at 10:29

2 Answers2

3

Do not even try to convert a content scheme to a file scheme.

There is no reason for it.

Please explain why you think you should.

// store path in shared preferences...

No. You should do that with

content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata

Then you can use it later.

Well if you made the obtained permissions persistent.

greenapps
  • 11,154
  • 2
  • 16
  • 19
  • I do not know, I just thought that it is the way how to achieve what I want. It is just an option I tried. So how do I use this content Uri I got from Intent and create a File object with it? – tomas Mar 19 '18 at 09:44
  • No. No File object. The File class is for a file scheme. But now you have a content scheme. If you want to create a file then do it in the modern way. Storage Access Framework. There are so many examples posted already here on stackoverflow. You can use DocumentFile.createFile() for creating a file. Just google. – greenapps Mar 19 '18 at 09:46
  • But I do not want to create a file. I pick a directory using an intent. Then I get this content Uri. I want to store it in shared preferences and now I would like to for example get parent directory of a directory i picked, or list all its files. The problem is I still do not understand how I should use this content Uri of a directory I picked and use it as normal File object. – tomas Mar 19 '18 at 10:07
  • You will not get the parent directory using DocumentFile.getParent(). But why would you? But you can list the files and folders in the picked directory using DocumentFile.listFiles(). Use the storage access framework! Modern times have come. You do not need the File class anymore. – greenapps Mar 19 '18 at 10:26
  • I am trying to create a simple file manager. And I want to have "default folder" option. So the user chooses a directory and then when he opens an app again there will be the default directory on the screen. Therefore I need to know parent directory when I navigate "up". In my app, I am using methods like Environment.getExternalStorageDirectory(), which returns File, and therefore I am working with File object everywhere. It all works fine, I just want to implement this default folder feature. – tomas Mar 19 '18 at 11:18
  • If you make a file manager or file explorer app then start with displaying getExternalFilesDir(). Why would you rely on anything different? You dont need a file picker too as your app will be the file or directory picker. – greenapps Mar 19 '18 at 14:14
0

I was trying to implement "default folder" function in my file manager app and to pick a directory I wanted to use some other app, but that did not work for me. But thanks to @greenapps I realized that I can select default folder within my own app.

tomas
  • 376
  • 1
  • 5
  • 17