13. Android Spinner Reading Data via FileInputStream Example

This entry is part 13 of 22 in the series Android-Intermediate

Android Spinner with fileinputstream exampleReading Information with FileInputStream

In this Android tutorial we will read internal application data via FileInputStream. Our Android spinner will display all saved files that we can read (which we have created in the previous tutorial). After we get our list of filenames, we will be able to select one of those files and load that data from that file and display the information within our TextView. Halloween is coming up tomorrow and working with the FileInputStream may be a little spooky for some. You have been warned! (Just kidding, it’s not that bad.)


The FileInputStream and the Black Hole Example


Reading Private Internal Data is Easy with Android!

Now that we know how to get the filenames of the data we saved into our Android application’s internal storage with the spinner element, it is time to learn how to read the stored information within that file. If you can remember back to the 9th tutorial in this series, we saved the data using something called the FileOutputStream. Well, FileOutputStream has a evil twin brother, FileInputStream, and he is the guy reads (or loads) the data from a file.

Let’s stay we save a journal entry with the filename of “the_day_I_got_attacked_by_unicorns”. Within this file is the story about the worst day of our lives maybe something like this:

“For the longest time I thought unicorns were magically creatures that spread joy and love upon the world with their rainbow farts. EFffFF that! Those horned bas***ds came from the skies a-blazin. You thought birds pooping on you was bad. You have nooooo idea what unicorns can do…”

I think you get the idea. We have a filename and some data stored within that file. Now, Android already knows where we stored this information because we saved it to the app’s private internal storage. Here’s a quick refresher of how we would have SAVED the data of this journey entry:

	        String FILENAME = "the_day_I_got_attacked_by_unicorns";
		String JOUR = "For the longest time I thought unicorns were magically creatures that spread joy and love upon the world with there rainbow farts.  EFffFF that!  Those horned bas***ds come from the skies a-blazin.  You thought birds pooping on you was bad.  You have nooooo idea what unicorns can..."
		
		try {
			FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
			fos.write(JOUR.getBytes());
			fos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

Easily enough right? So now lets look how to read this data with the FileInputStream. First, we will need a string to catch all of the data the we can read from the file. We shall call this string “value”. The next thing we will need is the FileInputStream, and it shall be named “fis”.

String value = "";
FileInputStream fis;

The FileInputStream is the exact opposite of the FileOutputStream, but I just like to think of it as a giant black hole. Besides reading data, it’s life mission is to suck up everything and destroy it.. well not really, now I might just be confusing you. But the reason I think of the FileInputStream as a black hole is because first it finds the name of the file it is suppose to open, and then it starts sucking in all of the data from that file.

fis = openFileInput("the_day_I_got_attacked_by_unicorns");

We will want to catch this data with in a byte array, because we will want to know how large the file is.

byte[] input = new byte[fis.available()];

Now that that we know how large the file is (in bytes) we want to start reading the bytes and converting them into a string. We will add the string value of data we are currently reading to the string that we setup before the FileInputStream black-hole-thing started doing it’s business. Lastly, we want to stay efficient and not try to read any data that never came into the black hole in the first place. We will use a while loop to read only the data that the fileInputStream picked up. Once there is no more data to be read from the file, fis.read(input); be equal to “-1″. Here’s how we piece it together:

while(fis.read(input) != -1){
	value += new String(input);
}

We also don’t want the FileInputStream to be open forever, always trying to suck in more data. So, make sure you close up the black hole whenever you open it:

fis.close();

If you have typed all of this into eclipse, you are probably noticing some red squiggle lines. Anytime, we are working with data (or black hole) there is a possibility of failure. We want to catch any exceptions that may arise. For example, if we tried opening the file “thedayIgotattackedbyunicorns” instead of “the_day_I_got_attacked_by_unicorns” we would get an error because that file doesn’t exist anywhere. We would like to catch that exception, with a try and catch. Our code now should look like this:

String value = "";
FileInputStream fis;
try {
	fis = openFileInput("the_day_I_got_attacked_by_unicorns");
	byte[] input = new byte[fis.available()];
	while(fis.read(input) != -1){
		value += new String(input);
	}
	fis.close();
} catch (FileNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} 

If the filename doesn’t exist it will catch that exception and print it to the stack trace, which is used for debugging. There is one more exception that may arise when we are working with data. The input/output exception. Let’s catch that one as well:

String value = "";
FileInputStream fis;
try {
	fis = openFileInput("the_day_I_got_attacked_by_unicorns");
	byte[] input = new byte[fis.available()];
	while(fis.read(input) != -1){
		value += new String(input);
	}
	fis.close();
} catch (FileNotFoundException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
} catch (IOException e) {
	// TODO Auto-generated catch block
	e.printStackTrace();
}

Our FileInputException should now work properly, however it will only try to open the “the_day_I_got_attacked_by_unicorns” file. We don’t want type this all out every time we want to read a file, so let’s make this process into a method that will read any filename coming into the method’s parameters.

private void openFile(String selectFile) {
	// TODO Auto-generated method stub
	String value = "";
	FileInputStream fis;
	
	try {
		fis = openFileInput(selectFile);
		byte[] input = new byte[fis.available()];
		while(fis.read(input) != -1){
			value += new String(input);
		}
		fis.close();
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

This method will successfully read the contents of a file, if that filename exist. However, we aren’t using the interpreted data for anything. So, let’s just set the text of a TextView to the value of the data we read. Here is the final result using an Android spinner to select the filename we want to read:

package com.mybringback.theworks;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class Reading extends Activity implements OnClickListener{
	
	Spinner spinner;
	TextView title, entry;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.reading);
		spinner = (Spinner)findViewById(R.id.spinner1);
		title = (TextView)findViewById(R.id.textView1);
		entry = (TextView)findViewById(R.id.textView2);
		getFilenames();
	}
	

	private void getFilenames() {
		// TODO Auto-generated method stub
		String[] filenames = getApplicationContext().fileList();
		List<String> list = new ArrayList<String>();
		for(int i = 0; i<filenames.length; i++){
			//Log.d("Filename", filenames[i]);
			list.add(filenames[i]);
		}
		ArrayAdapter<String> filenameAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, list);
		spinner.setAdapter(filenameAdapter);
	}


	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		String selectFile = String.valueOf(spinner.getSelectedItem());
		openFile(selectFile);
	}


	private void openFile(String selectFile) {
		// TODO Auto-generated method stub
		String value = "";
		FileInputStream fis;
		
		try {
			fis = openFileInput(selectFile);
			byte[] input = new byte[fis.available()];
			while(fis.read(input) != -1){
				value += new String(input);
			}
			fis.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		entry.setText(value);
		
	}
}

reading.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Load"
        android:onClick="onClick" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

Thanks again for coming to mybringback to learn Android programming. I look forward to hearing what you have to say on our facebook page, twitter, or in the forums. Thanks again!


Download the Source Code

Download the Completed Source Code


Navigation

Previous Lesson
Next Lesson

Author: trav

I'm just an average guy that love programming.

Share This Post On

Submit a Comment

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>