{"id":147,"date":"2014-05-26T07:17:51","date_gmt":"2014-05-26T11:17:51","guid":{"rendered":"https:\/\/cindypotvin.com\/?p=147"},"modified":"2017-06-03T11:04:51","modified_gmt":"2017-06-03T15:04:51","slug":"saving-data-to-a-file-in-your-android-application","status":"publish","type":"post","link":"https:\/\/cindypotvin.com\/saving-data-to-a-file-in-your-android-application\/","title":{"rendered":"Saving data to a file in your Android application"},"content":{"rendered":"
This is the second post in my series about storage in Android applications. The other post is available here :<\/p>\n
https:\/\/cindypotvin.com\/introduction-how-to-save-data-in-your-android-application\/<\/a><\/p>\n This post is about saving to a file from an Android application, which is the easiest way to store data. There are many situations where you may need to save a file : you may want to use an existing file format to create files that can be opened by the user in another application or the data is simple enough that it can be represented by a text file or a format like XML or YAML. For complex data a database may be a better option, since accessing and parsing a large file can be slow and there are no integrity checks unless you code them by hand. On the other hand, there is less overhead and it easier to work with files than debugging with the data in a database. Depending on how the user will interact (or not) with your files, you will need to decide first which kind of storage to use.<\/p>\n Each application has its own private internal storage to save files. This is the kind of storage to use if the user shouldn’t be able to modify the file from outside your application, and if other application shouldn’t be able to access those files. Since the internal storage is private to your application, the files will be deleted if your application is uninstalled. The internal storage is also where your application is installed by default, so your files will always be available. On some older or cheaper devices the internal storage is quite limited, so you need to be careful about the size of the data you save if you need to support those devices.<\/p>\n You should never hardcode the path to the storage directories, since the directory may changes depending on the version of the Android OS used.\u00a0 Also, Android 4.4 introduces the concept of multiple users : in that case, the internal and external storage depend on the user logged in and the files of the other users will be invisible. Here are some of the methods used to get the paths to the internal storage:<\/p>\n As you can see, the files are represented by the File<\/em> object from the java.io<\/em> namepace: there is no file object specific to the Android SDK and the standard Java APIs for reading and writing files are used. Also, there is no specific application permission to set in the Android manifest to use the internal storage since it is already private to the application.<\/p>\n In addition of the internal storage, there is an external storage space shared by all the applications that is kept when your application is uninstalled. This is the storage that is shown when using a file explorer application and when the device is plugged in your computer. It may be implemented as a SD card that can be removed or as a partition of the built-in storage in the device, so your application should be able to work even if the card is removed or changed. To check the current state of the external storage, you can call the getExternalStorageState()<\/em> method.<\/p>\n On device with many users (starting with Android 4.4), the external storage is specific to the current user and files for other users can’t be accessed. Also, there may be more than one external storage if the device has a built-in external storage which is a partition on the internal memory and a SD card: in that case, the built-in storage is the primary external storage. Reading files from the external storage requires the READ_EXTERNAL_STORAGE permission and writing or reading files requires the WRITE_EXTERNAL_STORAGE permission.<\/p>\n Here are the methods you should use to call to get the directories of the primary external storage:<\/p>\n To save a file, you need to get the path to the storage you want to use which is used the same way regardless of the type of storage used since all the methods returns a java.io.File<\/em> object representing the directory to use. Here is an example of using the external storage to save a text file from an Activity<\/em> :<\/p>\n And here is an example of how to read from the file you just wrote :<\/p>\n A runnable code example for all the snippets is available on my GitHub at https:\/\/github.com\/CindyPotvin\/androidreadwritefile<\/a>.Internal storage<\/h2>\n
\n
External storage<\/h2>\n
\n
\n<\/strong><\/strong><\/li>\n
\n<\/strong><\/li>\nExample code to save to a file<\/h2>\n
\r\ntry {\r\n \/\/ Creates a file in the primary external storage space of the\r\n \/\/ current application.\r\n \/\/ If the file does not exists, it is created.\r\n File testFile = new File(this.getExternalFilesDir(null), \"TestFile.txt\");\r\n if (!testFile.exists())\r\n testFile.createNewFile();\r\n\r\n \/\/ Adds a line to the file\r\n BufferedWriter writer = new BufferedWriter(new FileWriter(testFile, true \/*append*\/));\r\n writer.write(\"This is a test file.\");\r\n writer.close();\r\n \/\/ Refresh the data so it can seen when the device is plugged in a\r\n \/\/ computer. You may have to unplug and replug the device to see the\r\n \/\/ latest changes. This is not necessary if the user should not modify\r\n \/\/ the files.\r\n MediaScannerConnection.scanFile(this,\r\n new String[]{testFile.toString()},\r\n null,\r\n null);\r\n} catch (IOException e) {\r\n Log.e(\"ReadWriteFile\", \"Unable to write to the TestFile.txt file.\");\r\n}\r\n<\/pre>\n
\r\nString textFromFile = \"\";\r\n\/\/ Gets the file from the primary external storage space of the\r\n\/\/ current application.\r\nFile testFile = new File(this.getExternalFilesDir(null), \"TestFile.txt\");\r\nif (testFile != null) {\r\n StringBuilder stringBuilder = new StringBuilder();\r\n \/\/ Reads the data from the file\r\n BufferedReader reader = null;\r\n try {\r\n reader = new BufferedReader(new FileReader(testFile));\r\n String line;\r\n\r\n while ((line = reader.readLine()) != null) {\r\n textFromFile += line.toString();\r\n textFromFile += \"\\n\";\r\n }\r\n reader.close();\r\n } catch (Exception e) {\r\n Log.e(\"ReadWriteFile\", \"Unable to read the TestFile.txt file.\");\r\n }\r\n}\r\n<\/pre>\n