Android: Copy Asset To SD Card

Assets folder is where you can store some files for you app. Today I’m going to show you how to copy files from your android app’s asset’s folder to the device SD card. I used this when I have to deploy some default text files for my app and manipulate it at later time. Some existing android applications do this, they create folders with files inside on the first install. You can do the check if the file exists in the directory so you won’t have to copy the assets files every time.
By the way, the assets folder is included in your project package. If you’re using eclipse, you can see it in the package explorer. It looks like this:

An example assets folder. Image from http://goo.gl/ml9UD

An example assets folder. Image from http://goo.gl/ml9UD

In our example our assets has MyHtmlFiles folder with CodeOfANinja.html and ThankYou.html inside. Okay, so now we are going to code the app that:

  1. Copies 2 HTML files from the assets.
  2. Store to the device root directory.

If the HTML files were copied to your SD card, you can now manipulate its contents, rewrite it or make it a dynamic content and show it to your user anytime using the WebView. You can use this code for that.
Download code here:

Download Code

MainActivity.java code

package com.example.assetstosdcard;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.res.AssetManager;

public class MainActivity extends Activity {

    // Buffer size used.
    private final static int BUFFER_SIZE = 1024;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            AssetManager assetFiles = getAssets();

            // MyHtmlFiles is the name of folder from inside our assets folder
            String[] files = assetFiles.list("MyHtmlFiles");

            // Initialize streams
            InputStream in = null;
            OutputStream out = null;

            for (int i = 0; i < files.length; i++) {

                if (files[i].toString().equalsIgnoreCase("images")
                        || files[i].toString().equalsIgnoreCase("js")) {

                    
                     //  @Do nothing. images and js are folders but they will be
                     //  interpreted as files.
                      
                     //  @This is to prevent the app from throwing file not found
                     // exception.
                     

                } else {

                    
                     // @Folder name is also case sensitive
                     // @MyHtmlFiles is the folder from our assets
                     
                    in = assetFiles.open("MyHtmlFiles/" + files[i]);

                    
                     // Currently we will copy the files to the root directory
                     // but you should create specific directory for your app
                     
                    out = new FileOutputStream(
                            Environment.getExternalStorageDirectory() + "/"
                                    + files[i]);
                    copyAssetFiles(in, out);

                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void copyAssetFiles(InputStream in, OutputStream out) {
        try {

            byte[] buffer = new byte[BUFFER_SIZE];
            int read;

            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }

            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;

        } catch (IOException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

ActivityMain.xml code – This will what will be seen when our the code runs.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:text="CodeOfANinja.html and ThankYou.html should be copied to the root directory of your SD card by now."
        tools:context=".MainActivity" />

</RelativeLayout>

AndroidManifest.xml code – permission is WRITE_EXTERNAL_STORAGE since we are writing files to SD card.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.assetstosdcard"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

When our code runs:

Check your SD card when you see this.

Check your SD card when you see this.

Thanks for reading this Android: Copy Asset To SD Card!

Working with Text Files in Android

Today we are going to code about a sample app with some operations I usually play with text files in my Android applications. These operations would include creating, reading, updating,and deleting text files. I find these operations really useful when I have to store some data temporarily, creating some log files, or store some actual content just like what evernote does, see screenshot below.

Working with Text Files in Android

For apps like Evernote, storing some user content data on the device disk or sdcard is okay, some reason include, the device is a personal property, it is always with you. Another reason is, the data is “syncable”. If you think you lost some data in the device (like accidental file deletion), you can always simply sync and your data will come back to life in your device. I love cloud computing!
Below is the code download, basic CRUD codes and a Sample Application.

Download code here

Sample Application

txtlayout

In this sample application, when a user clicked a button:

  • Create Text File – a folder in your sdcard will be created with an empty text file in it (sdcard/MikeDalisayFolder/coan_log_file.txt)
  • Read Text File – the contents of coan_log_file.txt text file will be shown in the screen, you should click the update text file button first so it will have contents.
  • Update Text File – it will update our text file with two lines of text.
  • Delete Text File – it will delete our text file, of course. :)
  • We will use a TextFileHelper class I created. I believe you can see more useful techniques here like code re-usability and validation.

src/com.your.package/TextFileHelper.java code – This class contains our text file CRUD codes.

package com.example.textfilesexample;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

import android.content.Context;
import android.widget.Toast;

/*
 * This class is for text file CRUD.
 * You can just make flashMessage() a comment if you do not need it.
 */
public class TextFileHelper {

    // context is used for toasts
    Context mContext;

    /*
     * Constructor
     */
    public TextFileHelper(Context mContext) {
        this.mContext = mContext;
    }

    /*
     * Create a text file.
     */
    public void createTextFile(String actualFile) {
        try {

            File file = new File(actualFile);

            if (file.exists()) {
                flashMessage(“Text file already exists.”);
            } else {

                // create the text file
                if (file.createNewFile()) {
                    flashMessage(“Text file was created.”);
                } else {
                    flashMessage(“Unable to create text file.”);
                }

            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Read a text file.
     */
    public String readTextFile(String actualFile) {

        String contents = “”;

        try {

            // Get the text file
            File file = new File(actualFile);

            // check if file is not empty
            if (file.exists() && file.length() != 0) {

                // read the file to get contents
                BufferedReader br = new BufferedReader(new FileReader(file));
                String line;

                while ((line = br.readLine()) != null) {
                    // store the text file line to contents variable
                    contents += line + “n“;
                }

            } else {
                flashMessage(“Unable to read. File may be missing or empty.”);
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return contents;
    }

    /*
     * Update a text file.
     */
    public void updateTextFile(String actualFile, String contents) {
        try {

            File textFile = new File(actualFile);

            if (textFile.exists()) {

                // set to true if you want to append contents to text file
                // set to false if you want to remove preivous content of text
                // file
                FileWriter textFileWriter = new FileWriter(textFile, false);

                BufferedWriter out = new BufferedWriter(textFileWriter);

                // create the content string
                String contentString = new String(contents);

                // write the updated content
                out.write(contentString);
                out.close();

                flashMessage(“File was updated.”);

            } else {
                flashMessage(“Cannot update. File does not exist.”);
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Delete a text file.
     */
    public void deleteTextFile(String actualFile) {
        try {

            File file = new File(actualFile);

            if (file.exists()) {

                if (file.delete()) {
                    flashMessage(“Text file was deleted!”);
                } else {
                    flashMessage(“Unable to delete text file.”);
                }

            } else {
                flashMessage(“Unable to delete. File does not exist.”);
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Method to create path where our text file will be created.
     */
    public void createPath(String filePath) {
        try {

            File file = new File(filePath);

            if (file.isDirectory()) {
                flashMessage(“Path exists.”);
            }

            // create the directory
            else {
                if (file.mkdirs()) {
                    flashMessage(“Path was created.”);
                } else {
                    flashMessage(“Unable to create path.”);
                }

            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Just an extra method for displaying toasts.
     */
    public void flashMessage(String customText) {
        try {

            Toast.makeText(mContext, customText, Toast.LENGTH_SHORT).show();

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

src/com.your.package/MainActivity.java code

package com.example.textfilesexample;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity {

    // our TextFileHelper
    TextFileHelper TextFileH;

    // where our text file will be created
    String filePath = Environment.getExternalStorageDirectory() + “/MikeDalisayFolder/”;
    
    // name of our text file
    String fileName = “coan_log_file.txt”;
    
    // filePath and fileName combined
    String actualFile = filePath + fileName;
    
    TextView contentsTextView;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {

            // initialize our TextFileHelper here
            TextFileH = new TextFileHelper(MainActivity.this);

            // first, make sure the path to your text file is created
            TextFileH.createPath(filePath);
            
            // so we can show file contents to the user
            contentsTextView = (TextView) findViewById(R.id.contentsTextView);
            
            // here is the actual button listener
            View.OnClickListener handler = new View.OnClickListener() {

                public void onClick(View v) {

                    // we will use switch statement and just
                    // get the button’s id to make things easier
                    switch (v.getId()) {

                    // when create button was clicked
                    case R.id.createBtn:
                        TextFileH.createTextFile(actualFile);
                        contentsTextView.setText(“”);
                        break;

                    // when read button was clicked
                    case R.id.readBtn:
                        String contents = TextFileH.readTextFile(actualFile);
                        contentsTextView.setText(contents);
                        break;

                    // when update button was clicked
                    case R.id.updateBtn:
                        TextFileH.updateTextFile(actualFile, “Mike is so handsome!nNew line here!”);
                        contentsTextView.setText(“”);
                        break;

                    // when edit button was clicked
                    case R.id.deleteBtn:
                        TextFileH.deleteTextFile(actualFile);
                        contentsTextView.setText(“”);
                        break;
                    }
                }
            };

            // we will get the button views and set the listener (handler)
            findViewById(R.id.createBtn).setOnClickListener(handler);
            findViewById(R.id.readBtn).setOnClickListener(handler);
            findViewById(R.id.updateBtn).setOnClickListener(handler);
            findViewById(R.id.deleteBtn).setOnClickListener(handler);

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

AndroidManifest.xml code – the permission will be WRITE_EXTERNAL_STORAGE

<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
   package=“com.example.textfilesexample”
   android:versionCode=“1″
   android:versionName=“1.0″ >
    <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE” />
  
    <uses-sdk
       android:minSdkVersion=“8″
       android:targetSdkVersion=“15″ />

    <application
       android:icon=“@drawable/ic_launcher”
       android:label=“@string/app_name”
       android:theme=“@style/AppTheme” >
        <activity
           android:name=“.MainActivity”
           android:label=“@string/title_activity_main” >
            <intent-filter>
                <action android:name=“android.intent.action.MAIN” />

                <category android:name=“android.intent.category.LAUNCHER” />
            </intent-filter>
        </activity>
    </application>

</manifest>

res/layout/activity_main.xml code

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   xmlns:tools=“http://schemas.android.com/tools”
   android:layout_width=“match_parent”
   android:layout_height=“match_parent” >
    <Button
       android:id=“@+id/createBtn”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_alignParentTop=“true”
       android:text=“Create Text File” />

    <Button
       android:id=“@+id/readBtn”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_below=“@+id/createBtn”
       android:text=“Read Text File” />

    <Button
       android:id=“@+id/updateBtn”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_below=“@+id/readBtn”
       android:text=“Update Text File” />

    <Button
       android:id=“@+id/deleteBtn”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_below=“@+id/updateBtn”
       android:text=“Delete Text File” />

    <TextView
       android:id=“@+id/contentsTextView”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_below=“@+id/deleteBtn”
       android:text=“Text file contents should be here.” />

</RelativeLayout>

Some other notes:

  • You can create a text file with a different extension name and yet it will still be readable by your program. For example, you can make a file name like “my_file.coan”, evernote does “content.enml”. That file will not be easily read in the device since there are no app that can open a file with that extension. Your text file will be easily ignored by the users.
  • If you want to update a specific line of your text file, you have to read it first, track the line number, insert the updated line and use the code above.

Android libphonenumber Example

Today I want to show you a simple example code on how to use a very useful library called libphonenumber, a phone number handling library from Google. It can validate the correct number format for your country. In this example we’re using PH (Philippines) as country code. It is optimized for running on smartphones, and is used by the Android framework since 4.0 (Ice Cream Sandwich). Phone number validation is essential for your app so that you can get useful and sound phone numbers from your loyal users. Any verification code, messages or greetings that you want to send them will have lower chances of being missed.

Android libphonenumber Example

Example of a valid cellphone number.

You can download the code here:

DOWNLOAD SOURCE CODE

Online demo here.

Step 1

Download the latest JAR file here. As of this writing, I got libphonenumber-5.2v1.5.jar

Step 2

Copy the JAR file in the libs folder of your project.

libphonenumber

Step 3

Add the JAR on your project. Go to Properties > Java Build Path > Libraries Tab > Click Add Jars.. Button > Browse the JAR file on you libs and click OK. This is what it should look like:

projproperties

Step 4

Our sample XML layout file (activity_main.xml) will have the following code:

<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   xmlns:tools=“http://schemas.android.com/tools”
   android:layout_width=“match_parent”
   android:layout_height=“match_parent” >
    <EditText
       android:id=“@+id/phoneNumberEditText”
       android:layout_width=“match_parent”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_alignParentTop=“true”
       android:ems=“10″
       android:inputType=“phone” >

        <requestFocus />
    </EditText>

    <Button
       android:id=“@+id/validateButton”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_alignParentLeft=“true”
       android:layout_below=“@+id/phoneNumberEditText”
       android:text=“Validate Phone Number” />

</RelativeLayout>

Step 5

Our main activity will have the following code:

package com.example.libphonenumber;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try {
            // so that we can get the inputted phone number
            final EditText et = (EditText) findViewById(R.id.phoneNumberEditText);

            View.OnClickListener handler = new View.OnClickListener() {
                public void onClick(View v) {
                    
                    switch (v.getId()) {

                    // clicking the validate button
                    case R.id.validateButton:

                        // get the inputted phone number
                        String phoneNumber = et.getText().toString();
                        
                        // On our country, people are used to typing 7 (landline) or 11 (cellphone) digit numbers
                        // To make it 7 digit numbers valid, I have to prepend “02″
                        if (phoneNumber.length() == 7) {
                            phoneNumber = “02″ + phoneNumber;
                        }

                        // Use the library’s functions
                        PhoneNumberUtil phoneUtil = PhoneNumberUtil
                                .getInstance();
                        PhoneNumber phNumberProto = null;

                        try {

                            // I set the default region to PH (Philippines)
                            // You can find your country code here http://www.iso.org/iso/country_names_and_code_elements
                            phNumberProto = phoneUtil.parse(phoneNumber, “PH”);

                        } catch (NumberParseException e) {
                            // if there’s any error
                            System.err
                                    .println(“NumberParseException was thrown: “
                                            + e.toString());
                        }

                        // check if the number is valid
                        boolean isValid = phoneUtil
                                .isValidNumber(phNumberProto);

                        if (isValid) {

                            // get the valid number’s international format
                            String internationalFormat = phoneUtil.format(
                                    phNumberProto,
                                    PhoneNumberFormat.INTERNATIONAL);

                            Toast.makeText(
                                    getBaseContext(),
                                    “Phone number VALID: “ + internationalFormat,
                                    Toast.LENGTH_SHORT).show();

                        } else {

                            // prompt the user when the number is invalid
                            Toast.makeText(
                                    getBaseContext(),
                                    “Phone number is INVALID: “ + phoneNumber,
                                    Toast.LENGTH_SHORT).show();

                        }

                        break;

                    }
                }
            };

            // we will set the listeners
            findViewById(R.id.validateButton).setOnClickListener(handler);

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

Sample Output: (I felt like my phone is too small so I tested it on my tablet haha!)

An example of a valid land line number.

An example of a valid land line number.

Example of an invalid land line number.

Example of an invalid land line number.

Example of an invalid cellphone number.

Example of an invalid cellphone number.

That’s it! Happy New Year guys! :)