This post is a major update to a previous post on reading and writing text files using App Inventor. This revision includes information on how to locate the text files you create in your App Inventor apps, plus how to transfer those files from your smart phone or tablet to your computer.
An earlier blog post described how to store data using TinyDB so that an app’s data can persist between uses of the program, or even to share data between screens in a program.
Another way to save data is to write the data to a file on your Android device. App Inventor has introduced a File control that lets us write text data to a file and then read it back, later. As we will see, the File control is not the easiest thing to use but with some work, the control can be used to store data from our program into a file.
Once data is in a file, you could, hypothetically, transfer the file from an Android to device to another computer. Because Android stores the files in a way that they may not be readily accessible – or even visible – we need to use some simple tricks to find the file and transfer the file to a computer.
Update: To learn more about text files and transferring data in the CSV file format, check out Volume 3 of “App Inventor 2 Databases and Files” – thanks!
Let’s start our exploration of the File control in the Designer. Beneath the Palette heading, find the Storage item. Within Storage, find the File control. Drag and drop the File control on to your app. The control is placed below the user interface as it is an invisible control.
After dragging the File control, you’ll see something like this at the bottom of the user interface Designer:
The real work begins in the Blocks editor. For this example, we have just a few user interface components:
- btnAddItem – when pressed, it writes some items to a text file
- btnTestFetch – when pressed, it starts the process of reading the data from the text file back into the program
- txtBoxResult1 and txtBoxResult2 – a couple of text boxes that can be used to display the values read from the file.
In the Blocks editor, we will set up some blocks to write text to the file. We will start with a simple example:
btnAddItem.Click is an event handler and you should already be familiar with the concept of event handlers. The new features are those in purple, which reference the File1 control. Assuming you are implementing this in your own app, you should find the File1 control, probably at the bottom of the list of Blocks, at the left side of the Blocks editor.
The first purple item above, AppendToFile, writes a piece of text to the file indicated at the filename component. Writing to the file is the easy part!
When our app’s TestFetch button is pressed, the code initiates a read operation by reference ReadFrom and giving it the name of the file to read the data from. But at this point, the data has not yet been read!
When the data has actually been read, an event occurs and we need to add an event handler for GotText to process the data that has been read in to the app.
In the example above, the original text is read back from the file and placed in an on screen text box to illustrate success.
Writing and reading a single line of text is easy. But writing and reading a series of data elements is a bit more complex. There are several possible ways to handle this but I have chosen to use the mechanism.
But before we get started, let’s add a piece of code to help us during development: let’s always start with a clean data file by deleting the old file (if any) first. We can do this by adding the following code to the screen’s Initialize event:
Find your screen’s name in the Blocks list and then click the mouse over the screen name. You should see the Initialize event handler appear in a pop up list – drag that initialize block over to the Blocks editing window.
Let us now take a look at writing a list – or list of CSV rows to the text file. You’d best be familiar with lists (see volume 1 of my App Inventor 2: Tutorial) before starting on this.
(Note: the above text previously read “or list of lists”, but that was in error. This is a list of CSV rows. Thank you to Taifun for spotting the error).
For this example, we want to store a typical name/address combination. This means storing several items for each individual record – in our example, we have two individuals but this could be easily expanded to support more.
The first block creates two lists (at far right) – one list per person to combine the name and address.
These two lists are converted to the “CSV” (comma separate values) format and the two CSV rows are combined into a table. Think of this as being something like this:
- Alice Smith, 1234 Main St, Portlandia, USA
- Bob Smithy, 1234 Rural St, Portlandia, USA
Think of this as being like a spreadsheet with rows and columns, if you prefer. All those blue list processing blocks are converting our text input at right, into two CSV rows, combining those into a list, and then converting to a table. That’s a lot of work but its just a way of storing our more complex data into the file.
At the bottom block, the data read from the file is converted from text back in to table list format. And after this is done, individual list elements can be referenced. Since this table has two rows, index position 1 and index position 2 refer to first and second name records. Since each row is itself a list, we could also select the individual items from each name/address record if we wanted (but that is not shown in this example).
App Inventor’s new File control is helpful but remains cumbersome to use, as shown by the effort to read and write complex records. It works only with text (which is how most of App Inventor works) and it reads the entire file all at once, rather than reading a line at at time. This limits the total size of the file that we can likely handle (maximum size is not known).
Where is testfile2.txt stored on your phone?
Where the file is stored may depend upon whether the app is run using the AI 2 Companion on your phone, or if the app has been converted into a .apk file and installed on your phone like a traditional Android app. And whether your phone has an actual microSD card or a simulated sdcard.
When Run Using the AI 2 Companion
On my Nexus 5, there is a visible folder named AppInventor, and within that folder, there is a folder labeled data. This is where testfile2.txt is located.
This location corresponds to /storage/emulated/0/AppInventor/data on my phone, which is a folder on my phone. You will need a file explorer app – or connect your phone to a PC using a USB cable and mount the phone as an external hard drive – to see the file structure on the phone.
On an older LG Android phone running Android 2.2, files are written to an actual micro SD card. On the Nexus 5, there is no physical sdcard; however, Android creates a simulated sdcard.
When Built as a .apk File
When the app is built as a .apk executable and installed on the phone, the file that your app has created may be invisible! You can run your app – it will write to the file and read from the file, but the location of the file may be a mystery – apparently nowhere on your device!
Step 1: Install File Manager
To solve this problem, we must first create a file folder where the file should be stored. To create a file folder on your phone (or table), install an app from the Google Play store that lets you explore the file system on your device and create subdirectories in the file structure.
I use File Manager and recommend it.
Install this app and then use it to become familiar with the file and folder structure of your Android device.
Step 2: Create a file folder to store your app data files
For files that my own personal apps are creating and using, I create a folder named /pevest
Place the folder name in front of the filename, as shown here:
Step 3: Find the file!
If you connect your phone to your computer using a USB cable and mount the phone as a disk drive so that you can look at the files from your computer, you may discover your folder is missing!
(On Windows 7, I use Windows Explorer to view the files on the phone and the folder pevest is not visible on the phone.)
What happened? I have not thoroughly explored this topic but I believe the emulated storage (the simulated sdcard storage) uses a file system technology named ENT4 (like Windows OS uses FAT32 or NTFS file system technology and Mac OS X uses those plus the Mac OS X Journaled file system). The problem is ENT4 is not recognized by the Windows OS: the simulated sdcard storage is invisible to Windows.
Instead, go to the File Manager app that you installed and launch it. Navigate to /storage/emulated/0 directory – on my phone, the /pevest folder is located here:
Inside the /pevest folder is the file created by the app code, above:
Step 4: Sending the File to your computer
A simple way to copy the file to your computer is to email it from your phone (or tablet). Once the File Manager app has been installed, you can use it within GMail to navigate to your own file folder (/pevest in this example). In the GMail app, compose a message and click on the paperclip icon (for attaching files). Select the File Manager icon on the pop out menu (see example below), and then navigate to the folder and tap on your selected file to attach the file to your email. Email the file to yourself, log in on your computer and download the file from email.
Another way to copy the file is to use the excellent dooblou WiFi File Explorer app. Go to the Google Play store (follow the link) and install the app on your phone. WiFi Explorer turns your phone into a mini file server, accessible over your local WiFi network. You can access your phone (or tablet) using your Internet browser – for example, on my WiFi network, I type http://192.168.1.13:8000 in Chrome or IE or Firefox – and this displays the file directory of my phone (click on the next image to view full size):
Click on storage, shown in the left column, then click on emulated, and then click on 0 – and find your file directory (pevest, in this example). Open the directory and click on the file (testfile4.txt in this example) and the file is loaded into your browser window.
To Learn More About App Inventor Databases and Files
My 322 page e-book provides extensive guidance on App Inventor databases and files, including TinyDB, TinyWeb, Fusion Tables and text files.
- App Inventor 2 Databases and Files (Volume 3 e-book)
Step-by-step TinyDB, TinyWebDB, Fusion Tables and Files
Buy from: Amazon, Google Books, Kobo Books
Learn about all my App Inventor guide books, including sample chapters – here!
19 thoughts on “Updated: Writing and Reading Text Files Using App Inventor”
Igor Kuna liked this on Facebook.
Thank you for providing this tutorial. However there is one issue with your method of creating a list “of lists”, which has been discussed in the following thread in the App Inventor forum: https://groups.google.com/d/msg/mitappinventortest/0MaYmoHE18s/7D7NPjYSFQoJ
Therefore I suggest you to adjust your example to really create a list of lists instead of creating a list of “csv rows” as currently…
I’ll go back and take a look at what I was trying to accomplish with that example – to see whether a list of csv rows was, in fact, what was intended, but incorrectly described as a list of lists, or if I really should have a list of lists.
Thanks of the heads up!
The error was in the text. As you noted, I had written “list of lists” when it should have read “list of CSV rows”. I corrected the text – thank you for spotting that! Ed
in step 3 you are wondering, where the file is stored… the answer you can find in the documentation http://ai2.appinventor.mit.edu/reference/components/storage.html#File
“If the filename does not start with a slash, it will be written in the program’s private data directory where it will not be accessible to other programs on the phone. There is a special exception for the AI Companion where these files are written to /sdcard/AppInventor/data to facilitate debugging.”
The AppInventor folder only is available on your development device…
The problem is also that the file may be stored in an ENT4 file system partition, as it appears to be on my phone when I tested that. I was trying to address questions I received from readers as to why the file was not visible when the phone was connected to Windows via USB, and how they might go about finding the file on their phone. Many of the people using App Inventor were probably not familiar with the concept of file systems nor that their phone or tablet has a file system. It is definitely true that programs run in the AI Companion are handled quite a bit differently than apps that are built and installed separately and I think it is a good suggestion to make that more clear! Thanks!
ok can Edward M u help me i had made app in which i pick a file from SD card , i downloaded pdf reader , but when i run my app and pick a file from my android phone msg apears “no pdf reader is installed”
i had solved the problem , after 1 hour of comenting on this page
Igor Kuna liked this on Facebook.
and you seem to follow my question at the last part of the explanation…how do you split the individual items of each row? Thanks
I just arrived home from a week long vacation trip … I’ll take a look at your question in more detail after I get settled back into the regular routine! Sorry for the delay in responding… Ed
now my files saved in /storage/emulated/0/AppInventor/data
is there any possible way to save on my phone dropbox ?
My problem is create folder.
How to make app2 with cerate folder?
Because my ideas camera with picture save to folder.
I do not know of a way for an App Inventor app to create a folder; I think that feature is missing.
One can be created manually by using a separate File Manager app (free, in the Google Play Store).
Thanks for the great Tut. What happens when you need to
1. Read lets say a location (latitude, longitude and description) from a list or table of these, one record at a time? do you use a WHILE or For loop to access these values?
For a list, you can use the List method named “Is in list?” and pass to it the list to search, and the “thing” you wish to search for.
For a table, I suppose you could convert the table into a list and then use the List search. Use “List from CSV table”, from the List components.
Alternatively, yes, you could use a loop to scan through the list or table. But try using one of the built in searches first to see if that can solve your app requirement!