{"id":490,"date":"2015-01-05T16:27:51","date_gmt":"2015-01-06T00:27:51","guid":{"rendered":"http:\/\/appinventor.pevest.com\/?p=490"},"modified":"2015-01-05T16:27:51","modified_gmt":"2015-01-06T00:27:51","slug":"updated-writing-and-reading-text-files-using-app-inventor","status":"publish","type":"post","link":"https:\/\/coldstreams.com\/appinventor\/2015\/01\/05\/updated-writing-and-reading-text-files-using-app-inventor\/","title":{"rendered":"Updated: Writing and Reading Text Files Using App Inventor"},"content":{"rendered":"<p><b><i>This post is a major update to <a href=\"http:\/\/appinventor.pevest.com\/?p=67\">a previous post on reading and writing text files using App Inventor<\/a>. 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.<\/i><\/b><\/p>\n<p>An <a href=\"http:\/\/appinventor.pevest.com\/?p=58\">earlier blog post described how to store data using <em>TinyDB<\/em><\/a> so that an app&#8217;s data can persist between uses of the program, or even to share data between screens in a program.<\/p>\n<p>Another way to save data is to write the data\u00a0to a file on your Android device. App Inventor has introduced a <em>File<\/em> control that lets us write text data to a file and then read it back, later. As we will see, the <em>File<\/em> 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.<\/p>\n<p><em>Once data is in a file, you could, hypothetically, transfer the file\u00a0from an Android to device to another computer. Because Android stores the files in a way that they may not be readily accessible &#8211; or even visible &#8211; we need to use some simple tricks to find the file and transfer the file to a computer.<\/em><\/p>\n<p><em><strong>Update: To learn more about text files and transferring data in the CSV file format, check out <a href=\"http:\/\/appinventor.pevest.com\/?page_id=33\">Volume 3 of &#8220;App Inventor 2 Databases and Files&#8221;<\/a> &#8211; thanks!<\/strong><\/em><\/p>\n<p><!--more--><\/p>\n<p>Let&#8217;s start our exploration of the <em>File<\/em> control in the Designer. Beneath the <em>Palette<\/em> heading, find the <em>Storage<\/em> item. Within <em>Storage<\/em>, find the <em>File<\/em> control. Drag and drop the <em>File<\/em> control on to your app. The control is placed below the user interface as it is an <em>invisible<\/em> control.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIOControl.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-68 size-medium\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIOControl-142x300.png\" alt=\"FileIOControl\" width=\"142\" height=\"300\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>After dragging the <em>File<\/em> control, you&#8217;ll see something like this at the bottom of the user interface Designer:<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/File1Control.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-69\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/File1Control-300x105.png\" alt=\"File1Control\" width=\"300\" height=\"105\" \/><\/a>The real work begins in the Blocks editor. For this example, we have just a few user interface components:<\/p>\n<ul>\n<li><em>btnAddItem<\/em> &#8211; when pressed, it writes some items to a text file<\/li>\n<li><em>btnTestFetch<\/em> &#8211; when pressed, it starts the process of reading the data from the text file back into the program<\/li>\n<li><em>txtBoxResult1<\/em> and <em>txtBoxResult2<\/em> &#8211; a couple of text boxes that can be used to display the values read from the file.<\/li>\n<\/ul>\n<p>In the Blocks editor, we will set up some blocks to write text to the file. We will start with a simple example:<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIOSimpleEx.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-70\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIOSimpleEx-300x282.png\" alt=\"FileIOSimpleEx\" width=\"300\" height=\"282\" \/><\/a><\/p>\n<p><em>btnAddItem.Click<\/em> 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 <em>File1<\/em> control. Assuming you are implementing this in your own app, you should find the <em>File1<\/em> control, probably at the bottom of the list of Blocks, at the left side of the Blocks editor.<\/p>\n<p>The first purple item above, <em>AppendToFile<\/em>, writes a piece of text to the file indicated at the filename component. Writing to the file is the easy part!<\/p>\n<p>When our app&#8217;s TestFetch button is pressed, the code initiates a read operation by reference <em>ReadFrom<\/em> and giving it the name of the file to read the data from. But at this point, the data has not yet been read!<\/p>\n<p>When the data has actually been read, an event\u00a0occurs and we need to add an event handler for <em>GotText<\/em> to process the data that has been read in to the app.<\/p>\n<p>In the example above, the original text is read back from the file and placed in an on screen text box to illustrate success.<\/p>\n<p>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\u00a0mechanism.<\/p>\n<p>But before we get started, let&#8217;s add a piece of code to help us during development: let&#8217;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&#8217;s <em>Initialize<\/em> event:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-72\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIOSimpleDelete-300x71.png\" alt=\"FileIOSimpleDelete\" width=\"300\" height=\"71\" \/><\/p>\n<p>Find your screen&#8217;s name in the Blocks list and then click\u00a0the mouse over the screen name. You should see the <em>Initialize<\/em> event handler appear in a pop up list &#8211; drag that initialize block over to the Blocks editing window.<\/p>\n<p>Let us now take a look at writing a list &#8211; or list of CSV rows\u00a0to the text file. You&#8217;d best be familiar with lists (see volume 1 of my <strong><em>App Inventor 2: Tutorial<\/em><\/strong>) before starting on this.<\/p>\n<p><em>(Note: the above text previously read &#8220;or list of lists&#8221;, but that was in error. This is a list of CSV rows. Thank you to Taifun for spotting the error).<\/em><\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIO-Lists.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-73\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2014\/09\/FileIO-Lists-1024x709.png\" alt=\"FileIO-Lists\" width=\"625\" height=\"432\" \/><\/a><\/p>\n<p>For this example, we want to store a typical name\/address combination. This means storing several items for each individual record &#8211; in our example, we have two individuals but this could be easily expanded to support more.<\/p>\n<p>The first block creates two lists (at far right) &#8211; one list per person to combine the name and address.<\/p>\n<p>These two lists are converted to the &#8220;CSV&#8221; (comma separate values) format and the two CSV rows\u00a0are combined into a table. Think of this as being something like this:<\/p>\n<ol>\n<li>Alice Smith, 1234 Main St, Portlandia, USA<\/li>\n<li>Bob Smithy, 1234 Rural St, Portlandia, USA<\/li>\n<\/ol>\n<p>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&#8217;s a lot of work but its just a\u00a0way of storing our more complex data into the file.<\/p>\n<p>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).<\/p>\n<p>App Inventor&#8217;s new <em>File<\/em> control is helpful but remains cumbersome to use, as shown by the effort to read and write complex records. \u00a0It 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).<\/p>\n<h2>Where is testfile2.txt stored on your phone?<\/h2>\n<p>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.<\/p>\n<p><strong>When Run Using the AI 2 Companion<\/strong><\/p>\n<p>On my Nexus 5, there is a visible folder named <em>AppInventor<\/em>, and within that folder, there is a folder labeled <em>data<\/em>. This is where testfile2.txt is located.<\/p>\n<p>This location corresponds to <em>\/storage\/emulated\/0\/AppInventor\/data<\/em> on my phone, which is a folder on my\u00a0phone. You will need a file explorer app &#8211; or connect your phone to a PC using a USB cable and mount the phone as an external hard drive &#8211; to see the file structure on the phone.<\/p>\n<p>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.<\/p>\n<p><strong>When Built as a .apk File<\/strong><\/p>\n<p>When the app is built as a .apk executable and installed on the phone, the file that your app has created may be invisible!\u00a0You can run your app &#8211; it will write to the file and read from the file, but the location of the file may be a mystery &#8211; apparently\u00a0nowhere on your device!<\/p>\n<p><strong>Step 1: Install File Manager<\/strong><\/p>\n<p>To solve this problem, we must first create\u00a0a file folder where the file should be stored. To create a file folder on \u00a0your phone (or table),\u00a0install an app from the Google Play store that lets you explore the file system on your device and create subdirectories in the file structure.<\/p>\n<p>I use <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.rhmsoft.fm\">File Manager<\/a> and recommend it.<\/p>\n<p>Install this app and then use it to become familiar with the file and folder structure of your Android device.<\/p>\n<p><strong>Step 2: Create a file folder to store your app data files<\/strong><\/p>\n<p>For files that my own personal apps are creating and using, I create a folder named <em>\/pevest<\/em><\/p>\n<p>Place\u00a0the folder name in front of the filename, as shown here:<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/FileTextIODirectory.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-494\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/FileTextIODirectory.png\" alt=\"FileTextIODirectory\" width=\"437\" height=\"241\" \/><\/a><\/p>\n<p><strong>Step 3: Find the file!<\/strong><\/p>\n<p>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!<\/p>\n<p>(On Windows 7, I use Windows Explorer to view the files on the phone and the folder \\pevest is not visible on the phone.)<\/p>\n<p><em>What happened?<\/em> 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.<\/p>\n<p>Instead, go to the File Manager app that you installed and launch it. Navigate to <em>\/storage\/emulated\/0<\/em> directory &#8211; on my phone, the \/pevest folder is located here:<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-495\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-11-576x1024.png\" alt=\"Screenshot_2015-01-05-15-46-11\" width=\"336\" height=\"598\" \/><\/a><\/p>\n<p>Inside the <em>\/pevest<\/em> folder is\u00a0the file created by the app code, above:<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-17.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-496\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-17-576x1024.png\" alt=\"Screenshot_2015-01-05-15-46-17\" width=\"345\" height=\"613\" \/><\/a><\/p>\n<p><strong>Step 4: Sending the File to \u00a0your computer<\/strong><\/p>\n<p>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 (<em>\/pevest<\/em> 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.<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-48.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-497\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/Screenshot_2015-01-05-15-46-48-576x1024.png\" alt=\"Screenshot_2015-01-05-15-46-48\" width=\"345\" height=\"613\" \/><\/a><\/p>\n<p>Another way to copy the file is to use the excellent <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.dooblou.WiFiFileExplorer\">dooblou WiFi File Explorer<\/a> app. Go to the Google Play store (follow the <a href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.dooblou.WiFiFileExplorer\">link<\/a>) and install the app on your phone.\u00a0WiFi Explorer\u00a0turns your phone into a mini file server, accessible over your local WiFi network. You can access your phone (or tablet) using your Internet browser &#8211; for example, on my WiFi network, I type http:\/\/192.168.1.13:8000 in Chrome or IE or Firefox &#8211; and this displays the file directory of my phone (click on the next image to view full size):<\/p>\n<p><a href=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/WiFi1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-large wp-image-498\" src=\"http:\/\/appinventor.pevest.com\/wp-content\/uploads\/2015\/01\/WiFi1-1024x626.png\" alt=\"WiFi1\" width=\"625\" height=\"382\" \/><\/a><\/p>\n<p>Click on <em>storage<\/em>, shown in the left column, then click on <em>emulated<\/em>, and then click on <em>0<\/em> &#8211; and find your file directory (<em>pevest<\/em>, in this example). Open the directory and click on the file (<em>testfile4.txt<\/em> in this example) and the file is loaded into your browser window.<\/p>\n<h2>To Learn More About App Inventor Databases and Files<\/h2>\n<p>My 322 page e-book provides extensive guidance on App Inventor databases and files, including TinyDB, TinyWeb, Fusion Tables and text files.<\/p>\n<ul>\n<li><strong>App Inventor 2 Databases and Files<\/strong>\u00a0<strong>(Volume 3 e-book)<\/strong><br \/>\nStep-by-step TinyDB, TinyWebDB, Fusion Tables and Files<br \/>\nBuy from: <a href=\"http:\/\/amzn.to\/1UxQGSO\">Amazon<\/a>,<a href=\"https:\/\/play.google.com\/store\/books\/details\/Edward_Mitchell_App_Inventor_2_Databases_and_Files?id=ryB4CgAAQBAJ\"> Google Books<\/a>, <a href=\"https:\/\/store.kobobooks.com\/en-US\/ebook\/app-inventor-2-databases-and-files\">Kobo Books<\/a><\/li>\n<\/ul>\n<p>Learn about all my App Inventor guide books, including sample chapters &#8211; <a href=\"http:\/\/appinventor.pevest.com\/?page_id=33\">here<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <a href=\"https:\/\/coldstreams.com\/appinventor\/2015\/01\/05\/updated-writing-and-reading-text-files-using-app-inventor\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Updated: Writing and Reading Text Files Using App Inventor<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,10],"tags":[],"class_list":["post-490","post","type-post","status-publish","format-standard","hentry","category-components","category-programming-method"],"_links":{"self":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts\/490","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/comments?post=490"}],"version-history":[{"count":0,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/posts\/490\/revisions"}],"wp:attachment":[{"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/media?parent=490"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/categories?post=490"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/coldstreams.com\/appinventor\/wp-json\/wp\/v2\/tags?post=490"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}