[MUSIC] Handheld systems can generate and manipulate large amounts of data. So Android provides a number of support classes that allow you to manage data across multiple application sessions. In today's lesson, I'll talk about several of these support classes. I'll begin by talking about the SharedPreferences class, which allows applications to store and manage small amounts of primitive data. Next, I'll talk about writing files to both internal and external storage. And lastly, I'll finish up by discussing the creation and use of complex SQLite databases. Let's briefly discuss each of these storage options one at a time. Your applications will typically use the shared preferences class when you want to store small amounts of primitive data, such as a user name. Your applications will typically use internal device storage when you need to manage small to medium amounts of data that should remain private to the application, such as temporary files that are used by the application. Your applications will typically use external storage when you want to store larger amounts of non-private data, such as songs or video files. And your application will typically use databases when you intend to store small to large amounts of private, structured data. SharedPreferences are essentially persistent maps. And like any map, they hold key-value pairs of simple data types, things like strings and floats. And SharedPreferences are automatically persisted across application sessions. And this allows a user to create information during one use of an application, exit the application, restart it later, and still have access to the information they created earlier. SharedPreferences are often used for long-term storage of customizable application data, including things like a user name, favorite WiFi networks, or specific user options or preferences. To get a SharedPreferences object that is associated with a given activity, you can use the Activity.getPreferences method, passing in an access mode as a parameter. For example, this mode can be MODE_PRIVATE, indicating that the data is private to the calling application. If you want a SharedPreferences object that is not associated with a specific activity, then you can use the Context.getSharedPreferences method to retrieve a named SharedPreferences object. And with this method, you pass in a name for the SharedPreferences object and you pass in an access mode, such as the MODE_PRIVATE that we saw earlier. Once you've acquired a SharedPreferences object, you can edit that object by calling SharedPreferences.edit, and this method returns a SharedPreferences.editor instance. You can then add or change the values of the SharedPreferences object using methods such as putInt, putString and remove. And after you've made whatever changes you wanted to, you can then make those changes permanent by calling theSharedPreferences.Editor.commit method. And at this point, the SharedPreferences object is saved, and applications can exit knowing that their data can be retrieved during later application sessions. If an application later wants to read these values, it can get the SharedPreferences object again and then use various methods to read out the values that are stored within the object. For instance, it can call getAll to get the SharedPrefences values. It can call getBoolean to get a particular Boolean value, or it can call getString to get a particular string value. Our first example application in this lesson is called DataManagementSharedPreferences. This application has a button labeled Play, and when the user presses the Play button, the application displays a random number. The application keeps track of the highest number seen so far and saves that number across different user sessions. Let's run this application now. Now, I'll start the DataManagementSharedPreferences application. When this application starts, it shows that the high score is currently zero. When I press the Play button, you'll see that a new number is now displayed in the center of the screen. And since that number was higher than the previous high score, the high score display has been updated to show the new number. Now, remember this high score. I'm going to now quit this application. And now, I'll restart it. And as you can see, the current high score is the same high score that we saw from the last time we ran the application. Now, let me hit the Play button a few more times, so I'll increase the high score. There we go. And now, I'll stop the application again and restart it. And again, you can see that the application displays the high score that was set in the previous use of the application. Now, I can also hit the Reset button to reset that high score to zero. Let's look at the source code for this application. So, here's the application open in the IDE. Now, I'll open the main activity. In onCreate, the code acquires the SharedPreferences object for this activity. Next, when the user clicks the Play button, the code generates a new score, which it stores in a variable called val. After that, the code calls getInt on the preferences object to retrieve the current high score, if val is greater than the current high score, then we need to update the high score. So the code calls the edit method on the preferences object, which returns a SharedPreferences.Editor object. Next, the code calls the, calls putInt on the editor object to update the high score to the current value. Then finally, the code calls commit on the editor to save the current high score. As I said earlier, the SharedPreferences class is often used to store an application's user preferences. To make this easier, Android provides a class called PreferenceFragment that applications can use to display and modify user preferences. Our next example application is called DataManagementPreferenceFragment. This application uses a PreferenceFragment to display and modify an application's user preferences. In this case, the preference is the name that the application will use when addressing the user. Let's take a look at that application. Now, I'll start the DataManagementPreferenceFragment application. When this application starts up, it presents a single button labeled View User Name. When I click on this button, the PreferenceFragment will appear, allowing me to view my current user name and to change it if I wish. Let me do that now. And as you can see, my user name has not yet been set, so I'll click on this area. And now a dialogue box pops up, asking me to enter my user name. Let me do that now. And now, I'll click on the Submit button to accept this new user name. The dialogue box closes. And here you can see that my user name is now the name that I just entered. Now I'll close the application and restart it. I'll click again on the View User Name button. And as you can see, my user name is still Adam, so the information does indeed persist across user sessions. Let's take a look at the source code for this application. So here's the application open in IDE. Now, I'll open the ViewAndUpdatePreferences activity. This activity is the one that is started when the user clicks the View User Name button. The onCreate method first calls setContentView, passing in an XML file called user_prefs_fragment.xml. And this layout file instantiates and displays an instance of the UserPreferenceFragment class, which is defined in this file. Let's look at that class now. This class' onCreate method first calls addPreferencesFromResource method, passing in the user_prefs.xml file that's in the res/xml directory. Let's open that file. As you can see, this file defines a PreferenceScreen resource. This PreferenceScreen contains one preference that's displayed in an edit text box, and that preference has a key, the string uname, and is displayed with the title User Name. When the user clicks on the Edit textbox to change the user name, a dialogue box pops up with the title Change User Name, a subtitle or message saying, Enter Your User Name, and two buttons, labeled Cancel and Submit. In addition to preferences, Android supports the use of files. File is a class that represents a file system entity identified by a pathname. In Android, storage areas are classified as being either internal or external. Historically, this distinguished between the internal flash memory on a device and the removable external memory cards attached to the device. Nowadays, however, not all external memory is removable. Internal memory is usually used for smaller data sets that are private to an application. External memory, in contrast, is usually reserved for a larger, non-private data sets, things like music files and pictures. The example applications that we'll look at in just a second access and use files to store information. Two of the methods they use to do this are the openFileOutput method, which opens a private file for writing. And this method will create a physical file if it doesn't already exist. And there's also the openFileInput method, which opens a private file for reading. And there are, of course, many other file-related methods, so please look at the documentation for more information. The next example application is called DataManagementFileInternalMemory. When this application starts up, it checks whether a particular text file exists, and if it does not, the application then creates that file and writes some text into it. After that, the application opens that file, reads the text from it, and displays that text on the display. Let's take a look at this application. So here's my device. Now, I'll open the Data ManagementFileInternalMemory application. As you can see, the application has displayed some text on the screen. Let's look at the source code for this application to find out where that text came from. So here's the application open in the IDE. Now, I'll open the main activity for this application. And here in the onCreate method, the code first gets the FileStreamPath associated with the file name, testfile.txt. And if that file does not exist, then the code goes on to call the writeFile method. Let's scroll down and look at that method. Now, this method first calls the openFileOutput method, which returns a FileOutputSteam. The code then continues by writing three lines of text to that text file and finally, it closes the file. Now let's scroll back onto the onCreate method. Now the code continues by calling the readFile method, passing in a linear layout on which to display the text. The readFile method now opens the text file for input. And then begins to read each line out of the file. And each of these lines is then placed into a TextView and added to the linear layout