Reading Assets

In Chapter 2 we had a brief look at all the folders an Android project has. We identified the assets/ and res/ folders to be the ones we can put files in that should get distributed with our application. When we discussed the manifest file, I told you that we're not going to make use of the res/ folder, as it implies restrictions on how we structure our file set. The assets/ directory is the place to put all our files, in whatever folder hierarchy we want.

The files in the assets/ folder are exposed via a class called AssetManager. We can get a reference to that manager for our application as follows:

AssetManager assetManager = context.getAssets();

We already saw the Context interface earlier; it is implemented by the Activity class. In real life we'd fetch the AssetManager from our activity.

Once we have the AssetManager, we can start opening files like crazy: InputStream inputStream = assetManager.open("dir/dir2/filename.txt");

This method will return a plain-old Java InputStream, which we can use to read-in any sort of file. The only argument to the AssetManager.open() method is the filename relative to the asset directory. In the preceding example we have two directories in the assets/ folder, where the second one (dir2/) is a child of the first one (dir/). In our Eclipse project the file would be located in assets/dir/dir2/.

Let's write a simple test activity testing out this functionality. We want to load a text file named myawesometext.txt from a subdirectory of the assets/ directory called texts. The content of the text file will be displayed in a TextView. Listing 4-7 shows the source for this awe-inspiring activity.

Listing 4-7. AssetsTest.java, Demonstrating How to Read Asset Files package com.badlogic.androidgames;

import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream;

import android.app.Activity; import android.content.res.AssetManager; import android.os.Bundle; import android.widget.TextView;

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

AssetManager assetManager = getAssets(); InputStream inputStream = null; try {

inputStream = assetManager.open("texts/myawesometext.txt"); String text = loadTextFile(inputStream); textView.setText(text); } catch (IOException e) {

textView.setText("Couldn't load file"); } finally {

inputStream.close(); } catch (IOException e) {

textView.setText("Couldn't close file");

public String loadTextFile(InputStream inputStream) throws IOException { ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); byte[] bytes = new byte[4096]; int len = 0;

byteStream.write(bytes, 0, len); return new String(byteStream.toByteArray(), "UTF8");

No big surprises, other than that loading simple text from an InputStream is rather verbose in Java. I wrote a little method called loadTextFile() that will squeeze all the bytes out of the InputStream and return the bytes in the form of a string. I assume that the text file is encoded as UTF-8. The rest is just catching and handling various exceptions. Figure 4-10 shows you the output of this little activity.

Assets Test

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo dúo dolores et ea rebum. Stet dita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. Atvero eos et accusam et justo dúo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.

Figure 4-10. The text output

You should take away the following from this section:

Loading a text file from an InputStream in Java is a mess! Usually we'd do that with something like Apache lOUtils. I'll leave that up for you as an excercise.

We can only read assets, not write them.

We could easily modify the loadTextFile() method to load binary data instead. We would just need to return the byte array instead of the string.

0 0

Post a comment