How do you create a new file using file picker and write to it?

I can try to save a file, but I will not see the difference because I use Android 9 and the file picker approach also works for me.

it looks like you have to test this on a newer device to see the storage restrictions for newer devices
Taifun

Yes, I know.
I am now trying on an Android 10, this is the newest I have.
On this one the uri is of a different format, I need to experiment with it to get the file path out of it.
It would be nice to know what the syntax of an uri for a file is, but I could not find any documentation about it.
Is there by chance a resource where I can find how the app inventor handles it in the "read file" block?

you should test on Android 13+

do you plan to publish your app in Google Play?
If not you also can follow this suggestion

Taifun

the sources are here

Taifun

here is the result

the uri decode method of web component is not able to convert a content uri into a filepath
try one of the file extensions

EDIT: also I think, it is not necessary to do the conversion. If you own the file it theoretically should be possible to store it using the content uri...

EDIT: no, I was wrong, it produces the same runtime error as in your first post of this thread

example project attached
readWrite3.aia (64.1 KB)

  1. create file
  2. read file using the file picker
  3. save it using the provided content uri

Taifun

Thank you for the sources, I will check this out.

Yes, I read the guidance you linked and yes, I am planning to publish the app, so I do not want to ask for writing permission.

I do not want to use extensions, I want to keep it open to also publish on iOS

I will try to do some workaround and maybe use the file picker to find the directory and use the save option to create an empty file by the app before I fill it up with content.

If there is an example somewhere where I could see how to handle the file picker to look for directories, it would be helpful. Otherwise, I will need to experiment to see what the return value of the file picker is in the "select directory" mode.

It was new to me to hear that whatever the file picker creates from the app is not considered as created by the app, but that's life, I need to work around it.

Thanks for the help.

This is why I was surprised that this is simply not the case. On my Android 9, using the uri did not work when I tried to write in the file (see my code in my starting post), but I could write in the file after conversion.

I was wrong, see my updated answer

@ewpatton why is it not possible to use the file component and the SaveFile method together with a content uri provided by the file picker to store a file the app owns?

java.lang.IllegalArgumentException: URI scheme is not "file" at java.io.File.(File.java:429) at com.google.appinventor.components.runtime.util.ScopedFile.resolve(ScopedFile.java:65) at com.google.appinventor.components.runtime.File$9.processFile(File.java:628) at com.google.appinventor.components.runtime.util.SingleFileOperation.performOperation(SingleFileOperation.java:163) at com.google.appinventor.components.runtime.util.FileOperation.run(FileOperation.java:135) at java.lang.Thread.run(Thread.java:1119)

Taifun

Thank you for trying. As I said, I will do some workaround, but in your example the program did not even get to the point to try to write in the file, because the split of the uri did not give the file name. On your system a different split would be needed, but it is not worth trying it, because first of all, I beleive you that it will not work, and secondly, if the uri is this different on every system, thne there is no point trying to find a universal way of getting a file path out of it (although the app inventor file reading block manages to do it).

You could try with the SAF extension?

See HERE, scroll to Section 4 (Working with Text/CSV files in Shared Directories) of the guide.

Should work with all android versions.

Since I would like to keep it open to be available for iOS, I would like to stay away from extensions for the moment (although I do use the BLE extension to communicate with a microcontroller in the hope that at some point it will not be a problem for iOS either).

Is this a bug? I could not so far figure out a universal way of getting the file name and path out of the uri, it would be good to be able to write to a file where the user can look for the path, even if it is in a restricted location.

I know I asked this question a long time ago, but I would like to come back to it since I still don't know how to achieve my goals, which are the following:

  • I would like to be able to read a text file that the user saved on the device in a way that the user could search for it (from the app) using a file explorer.

  • I would like to store a text file in location that the user specifies through a file explorer in a way the user can access it with other apps.

I thought that I can do this using the file picker, but my efforts (like in my first post and in subsequent post of this thread) were not successful.

I know that android has a restriction on writing files, but still, are these unreasonable goals? Basic text editors (and plenty other apps) work like this.

Try this example (tested companion and compiled on Android 16)
crudtextfiles.aia (4.7 KB)

I used File component, TinyDB, Spinner and Listpicker.

(Note: I did not provide for user being able to add directories, nor test if a text file is edited by other apps)

Thank you, I try to play with this.

However, the main point of my question is about accessing files created by users and this approach does not seem to handle that (at least this is what I get from the note at the end of your message).

I checked that on Android 9 I can edit the created file (and I do not even have to create it from the app, I can access it if I type in the file name with path directly), but as I understand this may not be the case on newer Android versions.

It would also be good if this could be done in a somewhat interactive way. It is not really user friendly to ask them to type in the file name with a complete path. Isn't this what file picker is for?

Here's a simple app that lets you pick any (text) file – even one not created by the app – copy it to /Documents on Android 11+ without requiring storage permissions, and then have full access to it.

Of course, on Android < 11, WRITE_EXTERNAL_STORAGE permission must be requested. This generally applies to all directories except the ASD and PrivateDir.

My example app does both of these things...

Yes it does

If you want to create a file or a sub directory your user will have to type in the name.

I don't want to be ungrateful and I appreciate the help, but I really do not see how. If I click on "open" without doing anything else, an empty screen comes up. Maybe I missed something, but I cannot choose a file without me creating it first. When I open a normal text editor and select "open", it will bring up a search screen and I can choose a file that I want to edit. This is the functionality I am after.

If I want to open a file in any user friendly app, I do not have to type in anything. I simply use a file explorer from inside the app and click on the file I want to open.
If I want to save a file, I can choose a directory and type only the file name. I can even choose an existing file and edit the name or overwrite it (after a prompt if I really want to do this). This is what I call a user friendly approach.

I understand that I have to work doing it and I appreciate the help I get.

What I don't understand is why the file picker (which, as far as I see is exactly for this purpose) does not work.

Even in Anke's example (and in the examples in my previous posts), some juggling is needed to get the file name out of the uri returned by the file picker to be able to write to it.

The real file path wouldn't help you either, since you can't overwrite this file on Android 11+. As I've already explained, you first need to copy the file to one of the shared folders (e.g., /Documents) to gain full access, including write permissions.

Otherwise SAF (or MANAGE_EXTERNAL_STORAGE) must be used.


Achieving the desired functionality on iOS will likely remain a pipe dream. :wink: