Accessing the External Storage

While assets are superb for shipping all our images and sounds with our application, there are times when we need to be able to persist some information and reload it later on. A common example would be with high-scores.

Android offers many different ways of doing this: you can use local shared preferences of an application, a small SQLite database, and so on. All these options have one thing in common: they don't handle large binary files all that gracefully. Why would we need that anyway? While we can tell Android to install our application on the external storage, and thus not waste memory on the internal storage, this will only work on Android version 2.2 and above. For earlier versions all our application data would get installed on the internal storage. In theory we could only include the code of our application in the APK file and download all the asset files from a server to the SD card the first time our application is started. Many of the high-profile games on Android do this.

There are also other scenarios where we'd want to have access to the SD card (which is pretty much synonymous with the term external storage on all currently available devices). We could allow our users to create their own levels with an in-game editor. We'd need to store them somewhere, and the SD card is just perfect for that purpose.

So, now that I've convinced you not to use the fancy mechanisms Android offers us to store application preferences, let's have a look at how to read and write files on the SD card.

The first thing we have to do is request the permission to actually access the external storage. This is done in the manifest file with the <uses-permission> element as discussed earlier in this chapter.

The next thing we have to do is to check whether there is actually an external storage available on the device we run. For example, if you create an AVD, you have the option of not having it simulate an SD card, so you couldn't write to it in your application. Another reason for not getting access to the SD card could be that the external storage is currently in use by something else (e.g., the user may be exploring it via USB on a desktop PC). So here's how we get the state of the external storage:

String state = Environment.getExternalStorageState();

Hmm, we get a string. The Environment class defines a couple of constants. One of these is called Environment.MEDIA_MOUNTED. It is also a string. If the string returned by the preceding method equals this constant, we have full read/write access to the external storage. Note that you really have to use the equals() method to compare the two strings; reference equality won't work in every case.

Once we have determined that we can actually access the external storage, we need to get its root directory name. If we then want to access a specific file, we need to specify it relative to this directory. To get that root directory, we use another Environment static method:

File externalDir = Environment.getExternalStorageDirectory();

From here on we can use the standard Java I/O classes to read and write files.

Let's write a quick example that writes a file to the SD card, reads it back in, displays its content in a TextView, and then deletes the file from the SD card again. Listing 4-8 shows the source code for that.

Listing 4-8. The ExternalStorageTest Activity package com.badlogic.androidgames;

import; import; import; import; import; import;

import; import android.os.Bundle; import android.os.Environment; import android.widget.TextView;

public class ExternalStorageTest extends Activity { ^Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView textView = new TextView(this); setContentView(textView);

String state = Environment.getExternalStorageState(); if (!state.equals(Environment.MEDIA_MOUNTED)) {

textView.setText("No external storage mounted"); } else {

File externalDir = Environment.getExternalStorageDirectory(); File textFile = new File(externalDir.getAbsolutePath() + File.separator + "text.txt");

writeTextFile(textFile, "This is a test. Roger"); String text = readTextFile(textFile); textView.setText(text); if (!textFile.delete()) {

textView.setText("Couldn't remove temporary file");

textView.setText("something went wrong! " + e.getMessage());

private void writeTextFile(File file, String text) throws IOException { BufferedWriter writer = new BufferedWriter(new FileWriter(file)); writer.write(text); writer.close();

private String readTextFile(File file) throws IOException {

BufferedReader reader = new BufferedReader(new FileReader(file)); StringBuilder text = new StringBuilder(); String line;

while ((line = reader.readLine()) != null) { text.append(line); text.append("\n");

reader.close(); return text.toString();

First we check whether the SD card is actually mounted. If not we bail out early. Next we get the external storage directory and construct a new File instance that points to the file we are going to create in the next statement. The writeTextFile() method uses standard Java I/O classes to do its magic. If the file doesn't exist yet, this method will create it; otherwise it will overwrite an already existing file. After we successfully dump our test text to the file on the external storage, we read it in again and set it as the text of the TextView. As a final step we delete the file from the external storage again. All this is done with standard safety measures in place that will report if something went goes by outputting an error message to the TextView. Figure 4-11 shows the output of the activity.

External Storage Test

This is a test. Roger

Figure 4-11. Roger!

Here are the lessons to take away from this section:

Don't mess with any files that don't belong to you. Your users will be angry if you delete the photos of their last holiday.

Always check whether the external storage is mounted.

Do not mess with any of the files on the external storage! I mean it!

Seeing how easy it is to delete all the files on the external storage, you might think twice before you install your next app from the market that requests permissions to the SD card. The app has full control over your files once it's installed.

0 0

Post a comment