Android Basic Training Course: Accessing Files

    Although Android supports structured data storage - through the Preferences and the database, but sometimes, just a simple file and also to meet the demand for data storage. Android offering two ways to access files: one for the file type is packed with your application and a file type to be created by your application on the device.

    In this chapter, I presented a sample project to accessing 2 these type of files which an application usually interacts with them, hope that you can understand more about storing and retrieving files in Android. Source code now available on @Github.
DEMO VIDEO:

Assets Files - packed with your application

    These files located in main/assets/ folder. You can use it to store raw asset files. Files that you save here are compiled into an .apk file as-is, and the original file name is preserved. You can navigate this directory in the same way as a typical file system using URIs and read files as a stream of bytes using the AssetManager. For example, this is a good location for textures and game data.
    In general, assuming you have some static data want to include with the application, such as a list of words for a spelling checker. The easiest way to do this is to place the file in the res/assets folder, from which it will be placed inside the Android APK file of applications in the packaging process as a raw resource. Maybe I have a text file in it:
    Asset files also is a Resources type. In order to access it, you need an AssetManager instance, usually initialized by call getAssets() in your current Context (usually is an Activity). After that, like accessing file in Java platform, defining a BufferedReader object with InputStreamReader to read this text file line by line and show this content to a TextView after completed:
public void readAssetsFile() {
        String fileString = "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new InputStreamReader(getAssets().open("lorem_ipsum.txt"), "UTF-8"));

            // do reading, usually loop until end of file reading
            String line;
            while ((line = reader.readLine()) != null) {
                //process line
                fileString += line;
            }

            //set result to TextView after finish reading
            textView.setText(fileString);

        } catch (IOException e) {
            e.printStackTrace();
            textView.setError("Cannot open file!");
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    Invoking this method, in this case, when user click a Button:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        button1 = findViewById(R.id.btn_1);
        
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                readAssetsFile(); //read a file in res/assets folder
            }
        });
    }
    You will have a output screen like this (file content will be displayed):

    As note above, res/assets folder used for saving raw resource files. For another cases, you can save the database file (.db) or other file types which providing data to your application, readers find out yourself the way to access and use them!

Files in external memory - Huge storage space

    Besides the storage area on the application, you also access the external memory. It may be that the device, external memory cards such as SD card and micro SD, or as a hosted zone is designed to serve the role as an external memory.
    To access a file located in a folder of SD card, you must find the directory for the SD Card by using getExternalStorageDirectory() and specify the correct file name:
        //Find the directory for the SD Card using the API
        //*Don't* hardcode "/sdcard"
        File sdcard = Environment.getExternalStorageDirectory();

        //Get the text file based on folder
        File file = new File(sdcard, "Test/introduce.txt");
    In this case, we have a text file in "Test" folder in SD card:
    And this is full code for reading it, we also use BufferedReader initialized with a FileReader instance:
public void readFromSDcard() {
        //Find the directory for the SD Card using the API
        //*Don't* hardcode "/sdcard"
        File sdcard = Environment.getExternalStorageDirectory();

        //Get the text file based on folder
        File file = new File(sdcard, "Test/introduce.txt");

        //Read text from file
        StringBuilder text = new StringBuilder();

        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line;

            while ((line = br.readLine()) != null) {
                text.append(line);
                text.append('\n');
            }
            br.close();
        } catch (IOException e) {
            //You'll need to add proper error handling here
        }

        //Set the text
        textView.setText(text);
    }
    Invoking this method in onCreate():
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        button2 = findViewById(R.id.btn_2);

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                readFromSDcard();
            }
        });
    }
    The file content will displayed in the TextView:
    Note: You must declared reading external memory files permission in AndroidManifest.xml to use this feature:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    Absolutely similar with reading, you can write app data to a file in SD card by creating FileOutputStream and attach with it an OutputStreamWriter instance. Never forget call File.createNewFile() before writing data:
public void writeTextToFile() {
        if (editText.getText().toString().trim().equals("")) {
            Toast.makeText(this, "Please input some texts", Toast.LENGTH_SHORT).show();
        } else {
            try {
                File sdcard = Environment.getExternalStorageDirectory();

                //Get the text file based on folder
                File file = new File(sdcard, "Test/output.txt");
                file.createNewFile();

                FileOutputStream fOut = new FileOutputStream(file);
                OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);

                //get EditText content to OutputStreamWriter
                myOutWriter.append(editText.getText().toString().trim());

                myOutWriter.close();
                fOut.close();
                Toast.makeText(this, "Done writing File to SD card!", Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    Output when invoking this method - a Toast will show:
   And this text file now available in SD Card ("Test" folder):

    NOTE: Remember providing write data to SD card permission in AndroidManifest.xml to use this feature:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Other file type?

    Not only the text file, you can read/write other file types in Android. For example, as you see in picture above, I have an image file name "logo.png". By decode Bitmap with BitmapFactory, you can easily to get it to an ImageView:
ImageActivity.java
package info.devexchanges.accessingfiles;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;

import java.io.File;

public class ImageActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image);

        View button = findViewById(R.id.btn_get);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                File sdcard = Environment.getExternalStorageDirectory();

                //Get PNG file based on folder
                File imgFile = new File(sdcard, "Test/logo.png");

                if(imgFile.exists()){
                    //decode Bitmap by BitmapFactory
                    Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());

                    //set Bitmap to ImageView
                    ImageView imageView = (ImageView) findViewById(R.id.image);
                    imageView.setImageBitmap(bitmap);
                }
            }
        });
    }
}
    This is output screen:

Conclusions

    Storing and retrieving data in Android is quite hard to approach. From this post, readers can find out accessing/using many file types. You should also pay attention to security issues for your application when working with external memory, don't be leak your data! Finally, you can get full code of this project by clicking the button below.



Share


Previous post
« Prev Post
Next post
Next Post »