Posts

Android SQLite Transaction Example with INSERT Prepared Statement

Today I’m going to share an Android SQLite transaction example that I consider as one of the most useful test I made with Android SQLite. I’m really excited to share this since it helped me a lot and maybe it can help some more people as well.

This post will cover the following contents:

1.0 The Back Story
2.0 Insert Speed Problem
3.0 Android SQLite Transaction Example Source Code
4.0 Application Code Output
5.0 Other Tips On Improving Insert Speed

1.0 The Back Story

Recently, my app was required to download 30,000 records during sync. I think that’s a lot of data for a phone app, but that’s the way our app is.

The data were from a URL with data in JSON format. Our Android app has to read, parse and store the data on the device SQLite database.

30,000 records in one URL load is not advisable, we did several tests. I tried to parse it but failed, memory leaks occur, sometimes it was an out of memory error. So I tried some more test until I found the correct number of records per URL. 7,000 records and our app was able to read and parse it all. But to be safer, I made it to 5,000 records per page.

We had to paginate the download, so in our case, we had 6 pages. 6 pages x 5,000 records = 30,000. So yeah, it was very effective. All records were downloaded and inserted to the device SQLite database.

2.0 Insert Speed Problem

But before we were able to efficiently insert the records to the database, we run into the problem of “insert speed”. The usual insert command in Android is slow, so we had to use a transaction and prepared statement.

In our case, we use INSERT OR REPLACE INTO on the insert query since we want to update a row if it already exists, based on the trigger (INDEX) created.

If you’re using INSERT OR REPLACE INTO command, you have to create a trigger. This SQL trigger is executed after the table has been created (see DatabaseHandler.java below)

Another important factor in speeding up your insert is using prepared statements.

3.0 Android SQLite Transaction Example Source Code

Our source code will have three main files, the MainActivity.java, DatabaseHandler.java and activity_main.xml. I made the code as simple as possible for this example to be clear and easy to follow.

DOWNLOAD SOURCE CODE

MainActivity.java – our program’s first run, it also contains the AsyncTask that will be executed when the user clicks a button.

package com.example.androidsqlitetransaction;

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

public class MainActivity extends Activity {

    final String TAG = "MainActivity.java";
    EditText editTextRecordNum;
    TextView tvStatus;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

                switch (v.getId()) {

                case R.id.buttonNormalInsert:
                    new AsyncInsertData("normal").execute();
                    break;
                case R.id.buttonFastInsert:
                    new AsyncInsertData("fast").execute();
                    break;
                }
            }
        };

        // EditText for entering desired number of records to be inserted
        editTextRecordNum = (EditText) findViewById(R.id.editTextRecordNum);
        
        // Button for normal and fast insert
        findViewById(R.id.buttonNormalInsert).setOnClickListener(handler);
        findViewById(R.id.buttonFastInsert).setOnClickListener(handler);
        
        // status TextView
        tvStatus = (TextView) findViewById(R.id.textViewStatus);

    }

    // we used AsyncTask so it won't block the UI thread during inserts.
    class AsyncInsertData extends AsyncTask<String, String, String> {

        DatabaseHandler databaseHandler;
        String type;
        long timeElapsed;
        
        protected AsyncInsertData(String type){
            this.type  = type;
            this.databaseHandler = new DatabaseHandler(MainActivity.this);
        }
        
        // @type - can be 'normal' or 'fast'
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            tvStatus.setText("Inserting " + editTextRecordNum.getText() + " records...");
        }

        @Override
        protected String doInBackground(String... aurl) {

            try {

                // get number of records to be inserted
                int insertCount = Integer.parseInt(editTextRecordNum.getText().toString());
                
                // empty the table
                databaseHandler.deleteRecords();

                // keep track of execution time
                long lStartTime = System.nanoTime();
                
                if (type.equals("normal")) {
                    databaseHandler.insertNormal(insertCount);
                } else {
                    databaseHandler.insertFast(insertCount);
                }

                // execution finised
                long lEndTime = System.nanoTime();

                // display execution time
                timeElapsed = lEndTime - lStartTime;
                
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        protected void onPostExecute(String unused) {
            tvStatus.setText("Done inserting " + databaseHandler.countRecords() + " records. Time elapsed: " + timeElapsed / 1000000 + " ms."); 
        }
        
    }
}

DatabaseHandler.java – handles the database operations such as table creation, emptying the database, counting database records and the inserting our data using a loop.

package com.example.androidsqlitetransaction;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.util.Log;

public class DatabaseHandler extends SQLiteOpenHelper {

    // for our logs
    public static final String TAG = "DatabaseHandler.java";

    // database version
    private static final int DATABASE_VERSION = 7;

    // database name
    protected static final String DATABASE_NAME = "NinjaDatabase2";

    // table details
    public String tableName = "locations";
    public String fieldObjectId = "id";
    public String fieldObjectName = "name";
    public String fieldObjectDescription = "description";
    
    // constructor
    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // creating table
    @Override
    public void onCreate(SQLiteDatabase db) {

        String sql = "";

        sql += "CREATE TABLE " + tableName;
        sql += " ( ";
        sql += fieldObjectId + " INTEGER PRIMARY KEY AUTOINCREMENT, ";
        sql += fieldObjectName + " TEXT, ";
        sql += fieldObjectDescription + " TEXT ";
        sql += " ) ";

        db.execSQL(sql);

        // create the index for our INSERT OR REPLACE INTO statement.
        // this acts as the WHERE name="name input" AND description="description input"
        // if that WHERE clause is true, I mean, it finds the same name and description in the database,
        // it will be REPLACEd. 
        // ELSE, what's in the database will remain and the input will be INSERTed (new record)
        String INDEX = "CREATE UNIQUE INDEX locations_index ON " 
                        + tableName + " (name, description)";
        
        db.execSQL(INDEX);
    }

    
    // When upgrading the database, it will drop the current table and recreate.
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        String sql = "DROP TABLE IF EXISTS " + tableName;
        db.execSQL(sql);

        onCreate(db);
    }

    // insert data using transaction and prepared statement
    public void insertFast(int insertCount) {

        // you can use INSERT only
        String sql = "INSERT OR REPLACE INTO " + tableName + " ( name, description ) VALUES ( ?, ? )";
        
        SQLiteDatabase db = this.getWritableDatabase();
        
        /*
         * According to the docs http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
         * Writers should use beginTransactionNonExclusive() or beginTransactionWithListenerNonExclusive(SQLiteTransactionListener) 
         * to start a transaction. Non-exclusive mode allows database file to be in readable by other threads executing queries.
         */
        db.beginTransactionNonExclusive();
        // db.beginTransaction();
        
        SQLiteStatement stmt = db.compileStatement(sql);
        
        for(int x=1; x<=insertCount; x++){
            
            stmt.bindString(1, "Name # " + x);
            stmt.bindString(2, "Description # " + x);
            
            stmt.execute();
            stmt.clearBindings();
            
        }

        db.setTransactionSuccessful();
        db.endTransaction();
        
        db.close();
    }
    
    // inserts the record without using transaction and prepare statement
    public void insertNormal(int insertCount){
        try{
            
            SQLiteDatabase db = this.getWritableDatabase();
            
            for(int x=1; x<=insertCount; x++){
                
                ContentValues values = new ContentValues();
                values.put(fieldObjectName, "Name # " + x);
                values.put(fieldObjectDescription, "Description # " + x);
                
                db.insert(tableName, null, values);
                
            }
            
            db.close();
            
        }catch(Exception e){
            e.printStackTrace();
        } 
    }
    
    // deletes all records
    public void deleteRecords(){
        
        SQLiteDatabase db = this.getWritableDatabase();
        db.execSQL("delete from "+ tableName);
        db.close();
    }
    
    // count records
    public int countRecords(){
        
        SQLiteDatabase db = this.getWritableDatabase();
        
        Cursor cursor = db.rawQuery("SELECT count(*) from " + tableName, null);
        cursor.moveToFirst();
        
        int recCount = cursor.getInt(0);
        
        cursor.close();
        db.close();
        
        return recCount;
    }
    
}

activity_main.xml – the layout so we can enter the desired number of records to be inserted, choose whether we want it to be a ‘normal’ or ‘fast’ insert, and the status of the operation.

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/editTextRecordNum"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:inputType="number"
        android:singleLine="true"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/buttonNormalInsert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/editTextRecordNum"
        android:layout_below="@+id/editTextRecordNum"
        android:text="Normal Insert" />

    <Button
        android:id="@+id/buttonFastInsert"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/buttonNormalInsert"
        android:layout_alignBottom="@+id/buttonNormalInsert"
        android:layout_toRightOf="@+id/buttonNormalInsert"
        android:text="Fast Insert" />

    <TextView
        android:id="@+id/textViewStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/buttonNormalInsert"
        android:layout_below="@+id/buttonNormalInsert"
        android:padding="10dp"
        android:text="Status" />

</RelativeLayout>

4.0 Android SQLite Transaction Example Code Output

See our code’s output screenshots below…

When you entered 1000 as number of records to be inserted and pressed either the “Normal Insert” or “Fast Insert” button.

android sqlite transaction example

After inserting 1000 the “Normal Insert” way.

the normal insert way

After inserting 1000 the “Fast Insert” way.

the fast insert way - sqlite prepared statement

See the huge difference in insert speed? Inserting 1,000 records were from 54,615 milliseconds (almost 1 minute) down to 322 milliseconds!

5.0 Other Tips On Improving Insert Speed

Some other important points:

1. Do not put a “log” inside a loop, it affects the program execution and slows down the performance. For instance, Log.v(TAG, “Record was created.”); was inside a loop where you also insert the data.

2. Do not instantiate an object or class inside a loop, that’s the worst. The “new” keywords will slow down the performance. For instance, ValueConverter valueConverter = new ValueConverter(); will make you lonely for the rest of your life if it was inside a loop where you also insert the data.

If you have other thoughts or want to correct me, or something, please drop it in the comments section below. I’m willing to update this post for new information, ideas and tips that you can give. Thanks for reading this Android SQLite transaction example!

Simple Android JSON Parser Example Code with URL and Logcat Output

android json parser example

Today I’m going to share an Android JSON Parser example code to parse a JSON string from a URL.

This code is really useful because nowadays, JSON string is being used by most APIs like Facebook graph API and Google Maps.

You should use JSON in your projects instead of XML because it is lightweight, so much easier to parse, and is supported by most programming language.

Recently, I wrote about how to generate JSON string with PHP which can be useful for you too.

But if you really have to use XML, you can also take a look at my older post: Parse XML in Android With Three Input Sources

DOWNLOAD SOURCE CODE

We will cover the following contents in this post:

1.0 Creating JSON String
2.0 Creating our JSON Parser Class
3.0 Using JSON Parser Class with JSON String
4.0 Logcat Output
5.0 Online Resources

1.0 Creating JSON String

Create a JSON string and make it accessible via URL. I created an example for this post, you can see it in this URL: http://demo.codeofaninja.com/tutorials/json-example-with-php/index.php

What it looks like in a JSON viewer:

android-json-parser-example-json-string

As for the code on how to create that JSON string, you can take a look at my older post: Generating JSON String with PHP

2.0 Create our JSON Parser Class

You can use this JSON parser class with any of your JSON string from URL. Here’s our JsonParser.java:

package com.example.androidjsonparsing;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JsonParser {

    final String TAG = "JsonParser.java";

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    public JSONObject getJSONFromUrl(String url) {

        // make HTTP request
        try {

            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {

            BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();

        } catch (Exception e) {
            Log.e(TAG, "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e(TAG, "Error parsing data " + e.toString());
        }

        // return JSON String
        return jObj;
    }
}

3.0 Using JSON Parser Class with JSON String

Now we want to make use of our JSON parser with the generated JSON string from URL. But before running our code, make sure you enable internet permission in your AndroidManifest.xml

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

Now take a look at our MainActivity.java:

package com.example.androidjsonparsing;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;

public class MainActivity extends Activity {

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

        // we will using AsyncTask during parsing 
        new AsyncTaskParseJson().execute();
    }

    // you can make this class as another java file so it will be separated from your main activity.
    public class AsyncTaskParseJson extends AsyncTask<String, String, String> {

        final String TAG = "AsyncTaskParseJson.java";

        // set your json string url here
        String yourJsonStringUrl = "http://demo.codeofaninja.com/tutorials/json-example-with-php/index.php";

        // contacts JSONArray
        JSONArray dataJsonArr = null;

        @Override
        protected void onPreExecute() {}

        @Override
        protected String doInBackground(String... arg0) {

            try {

                // instantiate our json parser
                JsonParser jParser = new JsonParser();

                // get json string from url
                JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);

                // get the array of users
                dataJsonArr = json.getJSONArray("Users");

                // loop through all users
                for (int i = 0; i < dataJsonArr.length(); i++) {

                    JSONObject c = dataJsonArr.getJSONObject(i);

                    // Storing each json item in variable
                    String firstname = c.getString("firstname");
                    String lastname = c.getString("lastname");
                    String username = c.getString("username");

                    // show the values in our logcat
                    Log.e(TAG, "firstname: " + firstname 
                            + ", lastname: " + lastname
                            + ", username: " + username);

                }

            } catch (JSONException e) {
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String strFromDoInBg) {}
    }
}

4.0 Android JSON Parser Example Logcat Output

It is important for us to see the extracted data from the JSON string or URL. So here’s the logcat output of our code for today.

android-json-parsing-tutoril

5.0 Online Resources

I think the following online resources can also help you in doing such tasks. Check them out!

How to parse JSON in Android?
Android JSON Reader

If you have any other solutions or comments to improve this Android JSON parser example code, please let us know in the comments section below. Thanks for reading our code tutorial!

How to Send Data From Android to PHP Server? Android Post Request Help

Hi guys! Today we are going to code on how to send data from Android to PHP server. This is an example app that can post a file and text data to a web server with PHP file as a receiver. Having the ability to (do HTTP Post Request) post data from android app to remote server is required for most apps. Here are some example use of this functionality:

1. You want to get statistics on how your app is being used (you have to tell your user and they must agree of course!)
2. Your app has an upload file feature.
3. A user should register on your database before using more features of your app.

DOWNLOAD SOURCE CODE

Download HttpComponents Library

In this example, we are using a small library for posting a file, it is called the HttpComponents from the Apache Software Foundation. Please note that you won’t need this library if you’re just posting text data. The download can be found here: HttpComponents

  1. As of the moment, I downloaded the binary 4.2.3.zip
  2. When you extracted the zip file, find the lib folder and copy all the jar files there
  3. Copy those jar files to your project’s lib folder, here’s how to do that:
  4. Go to your workspace directory, find your project folder and inside, find the libs folder, put the jar files we extracted earlier
  5. Go back to eclipse and refresh your project files in the project explorer, now you can see the jar files inside your lib directory. See the screenshot below to visualize the goal of these 5 steps above.

Library Import - How to Send Data From Android to PHP Server?

How To Post Text Data?

// url where the data will be posted
String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
Log.v(TAG, "postURL: " + postReceiverUrl);

// HttpClient
HttpClient httpClient = new DefaultHttpClient();

// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);

// add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("firstname", "Mike"));
nameValuePairs.add(new BasicNameValuePair("lastname", "Dalisay"));
nameValuePairs.add(new BasicNameValuePair("email", "mike@testmail.com"));

httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();

if (resEntity != null) {
    
    String responseStr = EntityUtils.toString(resEntity).trim();
    Log.v(TAG, "Response: " +  responseStr);
    
    // you can add an if statement here and do other actions based on the response
}

How To Post A File?

You can use this code to post other file types such as an image.

// the file to be posted
String textFile = Environment.getExternalStorageDirectory() + "/sample.txt";
Log.v(TAG, "textFile: " + textFile);

// the URL where the file will be posted
String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
Log.v(TAG, "postURL: " + postReceiverUrl);

// new HttpClient
HttpClient httpClient = new DefaultHttpClient();

// post header
HttpPost httpPost = new HttpPost(postReceiverUrl);

File file = new File(textFile);
FileBody fileBody = new FileBody(file);

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", fileBody);
httpPost.setEntity(reqEntity);

// execute HTTP post request
HttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();

if (resEntity != null) {
    
    String responseStr = EntityUtils.toString(resEntity).trim();
    Log.v(TAG, "Response: " +  responseStr);
    
    // you can add an if statement here and do other actions based on the response
}

Complete Android Code on How to Send Data From Android to PHP Server

This is our MainActivity.java code. In this code, we are:

  • Using AsyncTask to prevent the network on main thread error.
  • To test posting the text data, you must change the actionChoice variable value to 1.
  • Else if you are to test posting a sample file, you must change the actionChoice to 2. Also, don’t forget to put a sample.txt file in your SD card root directory.
package com.example.androidpostdatatophpserver;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.app.Activity;

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity.java";
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // we are going to use asynctask to prevent network on main thread exception
        new PostDataAsyncTask().execute();
        
    }

    public class PostDataAsyncTask extends AsyncTask<String, String, String> {

        protected void onPreExecute() {
            super.onPreExecute();
            // do stuff before posting data
        }

        @Override
        protected String doInBackground(String... strings) {
            try {

                // 1 = post text data, 2 = post file
                int actionChoice = 2;
                
                // post a text data
                if(actionChoice==1){
                    postText();
                }
                
                // post a file
                else{
                    postFile();
                }
                
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String lenghtOfFile) {
            // do stuff after posting data
        }
    }
    
    // this will post our text data
    private void postText(){
        try{
            // url where the data will be posted
            String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
            Log.v(TAG, "postURL: " + postReceiverUrl);
            
            // HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            
            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);
    
            // add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("firstname", "Mike"));
            nameValuePairs.add(new BasicNameValuePair("lastname", "Dalisay"));
            nameValuePairs.add(new BasicNameValuePair("email", "mike@testmail.com"));
            
            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
    
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
            
            if (resEntity != null) {
                
                String responseStr = EntityUtils.toString(resEntity).trim();
                Log.v(TAG, "Response: " +  responseStr);
                
                // you can add an if statement here and do other actions based on the response
            }
            
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    // will post our text file
    private void postFile(){
        try{
            
            // the file to be posted
            String textFile = Environment.getExternalStorageDirectory() + "/sample.txt";
            Log.v(TAG, "textFile: " + textFile);
            
            // the URL where the file will be posted
            String postReceiverUrl = "http://yourdomain.com/post_data_receiver.php";
            Log.v(TAG, "postURL: " + postReceiverUrl);
            
            // new HttpClient
            HttpClient httpClient = new DefaultHttpClient();
            
            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);
            
            File file = new File(textFile);
            FileBody fileBody = new FileBody(file);
    
            MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
            reqEntity.addPart("file", fileBody);
            httpPost.setEntity(reqEntity);
            
            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
    
            if (resEntity != null) {
                
                String responseStr = EntityUtils.toString(resEntity).trim();
                Log.v(TAG, "Response: " +  responseStr);
                
                // you can add an if statement here and do other actions based on the response
            }
            
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The code above should give you a lot of clue on how to send data from Android to PHP server. But we have few more steps to do, continue to read below.

PHP file that will receive the posted data

This is the post_date_receiver.php code. You must upload it in your server and specify the URL to our MainActivity.java

<?php
// if text data was posted
if($_POST){
    print_r($_POST);
}

// if a file was posted
else if($_FILES){
    $file = $_FILES['file'];
    $fileContents = file_get_contents($file["tmp_name"]);
    print_r($fileContents);
}
?>

AndroidManifest.xml Code

Well, we are just having an INTERNET permission here.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.androidpostdatatophpserver"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET" />
    
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

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

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

</manifest>

Output Screenshots

Response is what post_date_receiver.php outputs when it receives the posted data.

android http example - posting text data output

Posting Text Data. The response array have our key-value pairs.

Posting Text File. The response is the content of my sample.txt file.

Posting Text File. The response is the content of my sample.txt file.

What do you think fo this code I came up with? If you have a better solution about how to send data from Android to PHP server, please let us know in the comments section below! We will add your solution or update this post if it deserves to, thanks!

Show ListView as Dropdown in Android – a Spinner Alternative

Our code for today will give us an alternative to using the Android spinner.

We will show ListView as dropdown in Android.

This ListView dropdown works just like a spinner but:

  • I love how it looks and response to user touch, it feels smoother and faster than a spinner.
  • It can also be easily customized, you won’t have to get stuck with default spinner look.
  • It can be triggered on any view elements such as a Button, Layout, TextView or EditText.

In this example, we are going to have a button that when it was touched, it will show a drop-down list of Dog names.

Here’s a video demo of our final output:

Show ListView as Dropdown in Android Complete Code

MainActivity.java – shows the button, set the items for the drop down list, creates the pop up window and then show it as drop down when the button was touched.

package com.example.showasdropdownexample;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.app.Activity;
import android.graphics.Color;

public class MainActivity extends Activity {

    String TAG = "MainActivity.java";

    String popUpContents[];
    PopupWindow popupWindowDogs;
    Button buttonShowDropDown;

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

        // initialize pop up window items list
        
        // add items on the array dynamically
        // format is DogName::DogID
        List<String> dogsList = new ArrayList<String>();
        dogsList.add("Akita Inu::1");
        dogsList.add("Alaskan Klee Kai::2");
        dogsList.add("Papillon::3");
        dogsList.add("Tibetan Spaniel::4");

        // convert to simple array
        popUpContents = new String[dogsList.size()];
        dogsList.toArray(popUpContents);

        
        // initialize pop up window
        popupWindowDogs = popupWindowDogs();

        
        // button on click listener
        
        View.OnClickListener handler = new View.OnClickListener() {
            public void onClick(View v) {                                                                                                                                                                                                                                                                                                 

                switch (v.getId()) {

                case R.id.buttonShowDropDown:
                    // show the list view as dropdown
                    popupWindowDogs.showAsDropDown(v, -5, 0);
                    break;
                }
            }
        };

        // our button
        buttonShowDropDown = (Button) findViewById(R.id.buttonShowDropDown);
        buttonShowDropDown.setOnClickListener(handler);
    }

    public PopupWindow popupWindowDogs() {

        // initialize a pop up window type
        PopupWindow popupWindow = new PopupWindow(this);

        // the drop down list is a list view
        ListView listViewDogs = new ListView(this);
        
        // set our adapter and pass our pop up window contents
        listViewDogs.setAdapter(dogsAdapter(popUpContents));
        
        // set the item click listener
        listViewDogs.setOnItemClickListener(new DogsDropdownOnItemClickListener());

        // some other visual settings
        popupWindow.setFocusable(true);
        popupWindow.setWidth(250);
        popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
        
        // set the list view as pop up window content
        popupWindow.setContentView(listViewDogs);

        return popupWindow;
    }

    /*
     * adapter where the list values will be set
     */
    private ArrayAdapter<String> dogsAdapter(String dogsArray[]) {

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, dogsArray) {

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {

                // setting the ID and text for every items in the list
                String item = getItem(position);
                String[] itemArr = item.split("::");
                String text = itemArr[0];
                String id = itemArr[1];

                // visual settings for the list item
                TextView listItem = new TextView(MainActivity.this);

                listItem.setText(text);
                listItem.setTag(id);
                listItem.setTextSize(22);
                listItem.setPadding(10, 10, 10, 10);
                listItem.setTextColor(Color.WHITE);
                
                return listItem;
            }
        };
        
        return adapter;
    }
}

DogsDropdownOnItemClickListener.java – triggered when an item on the drop down list was touched, it will change the text on the button and show a toast with the ID of the selected item.

package com.example.showasdropdownexample;

import android.content.Context;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;

public class DogsDropdownOnItemClickListener implements OnItemClickListener {

    String TAG = "DogsDropdownOnItemClickListener.java";
    
    @Override
    public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) {

        // get the context and main activity to access variables
        Context mContext = v.getContext();
        MainActivity mainActivity = ((MainActivity) mContext);
        
        // add some animation when a list item was clicked
        Animation fadeInAnimation = AnimationUtils.loadAnimation(v.getContext(), android.R.anim.fade_in);
        fadeInAnimation.setDuration(10);
        v.startAnimation(fadeInAnimation);
        
        // dismiss the pop up
        mainActivity.popupWindowDogs.dismiss();
        
        // get the text and set it as the button text
        String selectedItemText = ((TextView) v).getText().toString();
        mainActivity.buttonShowDropDown.setText(selectedItemText);
        
        // get the id
        String selectedItemTag = ((TextView) v).getTag().toString();
        Toast.makeText(mContext, "Dog ID is: " + selectedItemTag, Toast.LENGTH_SHORT).show();
        
    }

}

activity_main.xml – Here is the XML layout file we used for the user interface of our example.

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/buttonShowDropDown"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Select your dog..." />

</RelativeLayout>

That’s the solution I got on how to show ListView as dropdown in android. If you have any other solutions or suggestions to improve or rewrite this code, please let us know in the comments section below.

Android Bluetooth Printing Example Code with Actual Printer Device

Android Bluetooth Printing Example Code with Actual Printer Device

Android Bluetooth Printing Example Code with Actual Printer Device

Recently, I was asked to make a program for printing some data to a small or handheld Bluetooth printer device.

This can be used for printing receipts, simple tickets, or customer notes.

I like how it works because usually, we are getting our program output on a computer screen.

But this time we are getting our output on a tangible paper!

This code will simply let you connect to the Bluetooth printer, type a text that you want to be printed and click the “send” button to print.

As for the printing with images, we made another code for that, please see section 4.3 (April 15, 2015 update) below!

1.0 Bluetooth Printing Source Codes

Step 1: Put the following code on your MainActivity.java. These imports are needed to perform our Android printing operations via Bluetooth.

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;
import android.widget.Button;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends Activity {

}

Step 2: Inside your MainActivity class will be the following variable declarations.

// will show the statuses like bluetooth open, close or data sent
TextView myLabel;

// will enable user to enter any text to be printed
EditText myTextbox;

// android built in classes for bluetooth operations
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mmSocket;
BluetoothDevice mmDevice;

// needed for communication to bluetooth device / network
OutputStream mmOutputStream;
InputStream mmInputStream;
Thread workerThread;

byte[] readBuffer;
int readBufferPosition;
volatile boolean stopWorker;

Step 3: After the variable codes, we will have the following onCreate() method.

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

    try {
        // more codes will be here
    }catch(Exception e) {
        e.printStackTrace();
    }
}

Step 4: Our XML layout file called activity_main.xml located in res/layout/ directory will have the following codes.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_margin="10dp">

    <TextView
        android:id="@+id/label"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Type here:" />

    <EditText
        android:id="@+id/entry"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/label" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/entry">

        <Button
            android:id="@+id/open"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dip"
            android:text="Open" />

        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send" />

        <Button
            android:id="@+id/close"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Close" />
    </LinearLayout>
</RelativeLayout>

Step 5: Inside the try-catch of your onCreate() method we will define the TextView label, EditText input box and buttons based on our XML layout file in Step 4.

// we are going to have three buttons for specific functions
Button openButton = (Button) findViewById(R.id.open);
Button sendButton = (Button) findViewById(R.id.send);
Button closeButton = (Button) findViewById(R.id.close);

// text label and input box
myLabel = (TextView) findViewById(R.id.label);
myTextbox = (EditText) findViewById(R.id.entry);

Step 6: We will set the onClickListener of our open button. This will open the connection between the android device and Bluetooth printer.

// open bluetooth connection
openButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        try {
            findBT();
            openBT();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

Step 7: findBT() method will try to find available Bluetooth printer. It will not work without the following code. Put it below the onCreate() method.

// this will find a bluetooth printer device
void findBT() {

    try {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if(mBluetoothAdapter == null) {
            myLabel.setText("No bluetooth adapter available");
        }

        if(!mBluetoothAdapter.isEnabled()) {
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }

        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();

        if(pairedDevices.size() > 0) {
            for (BluetoothDevice device : pairedDevices) {
                
                // RPP300 is the name of the bluetooth printer device
                // we got this name from the list of paired devices
                if (device.getName().equals("RPP300")) {
                    mmDevice = device;
                    break;
                }
            }
        }

        myLabel.setText("Bluetooth device found.");

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

Step 8: openBT() method will open the connection to Bluetooth printer found during the findBT() method. It will not work without the following code. Put it below the findBT() method.

// tries to open a connection to the bluetooth printer device
void openBT() throws IOException {
    try {

        // Standard SerialPortService ID
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
        mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
        mmSocket.connect();
        mmOutputStream = mmSocket.getOutputStream();
        mmInputStream = mmSocket.getInputStream();

        beginListenForData();

        myLabel.setText("Bluetooth Opened");

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

Step 9: We need beginListenForData() method so that openBT() method will work.

/*
 * after opening a connection to bluetooth printer device,
 * we have to listen and check if a data were sent to be printed.
 */
void beginListenForData() {
    try {
        final Handler handler = new Handler();
        
        // this is the ASCII code for a newline character
        final byte delimiter = 10;

        stopWorker = false;
        readBufferPosition = 0;
        readBuffer = new byte[1024];
        
        workerThread = new Thread(new Runnable() {
            public void run() {

                while (!Thread.currentThread().isInterrupted() && !stopWorker) {
                    
                    try {
                        
                        int bytesAvailable = mmInputStream.available();

                        if (bytesAvailable > 0) {

                            byte[] packetBytes = new byte[bytesAvailable];
                            mmInputStream.read(packetBytes);

                            for (int i = 0; i < bytesAvailable; i++) {

                                byte b = packetBytes[i];
                                if (b == delimiter) {

                                    byte[] encodedBytes = new byte[readBufferPosition];
                                    System.arraycopy(
                                        readBuffer, 0,
                                        encodedBytes, 0,
                                        encodedBytes.length
                                    );

                                    // specify US-ASCII encoding
                                    final String data = new String(encodedBytes, "US-ASCII");
                                    readBufferPosition = 0;

                                    // tell the user data were sent to bluetooth printer device
                                    handler.post(new Runnable() {
                                        public void run() {
                                            myLabel.setText(data);
                                        }
                                    });

                                } else {
                                    readBuffer[readBufferPosition++] = b;
                                }
                            }
                        }
                        
                    } catch (IOException ex) {
                        stopWorker = true;
                    }
                    
                }
            }
        });

        workerThread.start();

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

Step 10: We will make an onClickListener for the “Send” button. Put the following code after the onClickListener of the “Open” button, inside onCreate() method.

// send data typed by the user to be printed
sendButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        try {
            sendData();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

Step 11: sendData() method is needed so that the “Open” button will work. Put it below the beginListenForData() method code block.

// this will send text data to be printed by the bluetooth printer
void sendData() throws IOException {
    try {
        
        // the text typed by the user
        String msg = myTextbox.getText().toString();
        msg += "\n";
        
        mmOutputStream.write(msg.getBytes());
        
        // tell the user data were sent
        myLabel.setText("Data sent.");
        
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Step 12: We will code an onClickListener for the “close” button so we can close the connection to Bluetooth printer and save battery. Put the following code after the onClickListener of the “Send” button, inside onCreate() method.

// close bluetooth connection
closeButton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        try {
            closeBT();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
});

Step 13: closeBT() method in Step 12 will not work without the following code. Put it below the sendData() method code block.

// close the connection to bluetooth printer.
void closeBT() throws IOException {
    try {
        stopWorker = true;
        mmOutputStream.close();
        mmInputStream.close();
        mmSocket.close();
        myLabel.setText("Bluetooth Closed");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Step 14: Make sure the BLUETOOTH permission was added to your manifest file. It is located in manifests/AndroidManifest.xml, the code inside should look like the following.

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

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

    <supports-screens android:anyDensity="true" />

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

    <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>

2.0 LEVEL 1 Source Code Output

Step 1: Click the “Open” button, the “Type here” text will change to “Bluetooth Opened”
Step 2: Type any text in the text box or EditText.
Step 3: Click the “Send” button, Bluetooth Printer device will print the text you typed in Step 2.
Step 4: Click the “Close” button to close Bluetooth connection and save battery.

Need to buy the same printer model we used above? I will give you the contact information of our supplier. Send an email to mike@codeofaninja.com with a subject “Bluetooth printer by codeofaninja.com”. I will reply with the contact information of our supplier.

3.0 LEVEL 2 Source Code Output

The LEVEL 2 source code can print small images. As you will see in the video, you can browse the image and then the Bluetooth printer will print it.

Need to buy the same printer model we used above? I will give you the contact information of our supplier. Send an email to mike@codeofaninja.com with a subject “Bluetooth printer by codeofaninja.com”. I will reply with the contact information of our supplier.

Please note that you have to pair your Android device (in your Bluetooth settings) and Bluetooth printer before running our source code.

4.0 Download Source Code

4.1 Downloading The Source Code

You can get the source code by following the source code above. But isn’t it more convenient if you can just download the complete source code we used, import it and play around it?

There’s a small fee in getting the complete source code, it is small compared to the value, skill upgrade, and career upgrade it can bring you, or income you can get from your android app project or business.

Download the source code by clicking the “Buy Now” button below. What will you get? The source codes and free code updates!

4.2 LEVEL 1 Source Code

LEVEL 1 is the complete source code of our tutorial above.

DOWNLOAD NOW

4.3 LEVEL 2 Source Code

Here’s the source code version where you can print images (see output video demo on section 3.0 above). The source code can let you browse an image and then print it in the Bluetooth printer.

Images must be small and less than 10KB in size only, anything more than that, the printing will fail.

DOWNLOAD NOW

4.4 Download ALL LEVELS Source Code

This means you will download LEVEL 1 and LEVEL 2 source codes above at a discounted price.

DOWNLOAD NOW

IMPORTANT NOTE: This code was only tested with the printer we specified above. It may not work with your kind of printer. We provide the code as is. Download it at your own risk.

Also, thanks to a code from project green giant for helping me figure out this Android Bluetooth printing code example.

android sqlite database crud tutorial with example app

Android SQLite Database CRUD Tutorial with Example Application

android-sqlite-database-crud-tutorial-min

This is a step by step android CRUD tutorial where we’ll create an Android application that demonstrates Android’s SQLite database capabilities.

Operations such as create, read, update and delete (CRUD) in Android is an essential skill every aspiring Android developer must have.

In this post, we will cover the following contents:

Read more

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 Camera Code Tutorial

Today we are going to do a code that can enable your android application to capture images using the device camera. In this example code, we will have:

  1. A “Take Picture” button on our main activity, when the user clicks it, the device camera will be shown that will enable your user the take a picture.
  2. After taking a picture, the preview of the image will be shown with options to “Save” or “Discard” the image.
  3. If the user tapped “Save”, the image will be saved on the directory we specified in our code, else, if the user tapped “Discard”, the device camera will be shown again.
  4. If the user saved the image, he will be asked if he wants to take another picture.

Android Camera Code Tutorial

DOWNLOAD SOURCE CODE

Our MainActivity.java code – This activity will show our “Take Picture” button.

package com.example.camerahelper;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.view.View;

public class MainActivity extends Activity {

    Context mContext;

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

        mContext = MainActivity.this;

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

                switch (v.getId()) {

                case R.id.takePicture:
                    // go to camera activity
                    Intent nextActivity = new Intent(mContext,
                            CameraActivity.class);
                    startActivity(nextActivity);
                    break;

                }
            }
        };

        findViewById(R.id.takePicture).setOnClickListener(handler);

    }

}

Our res/layout/activity_main.xml – The XML layout file for our MainActivity.

<?xml version=“1.0″ encoding=“utf-8″?>
<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   android:id=“@+id/widget29″
   android:layout_width=“fill_parent”
   android:layout_height=“fill_parent” >
    <Button
       android:id=“@+id/takePicture”
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:layout_centerHorizontal=“true”
       android:layout_centerVertical=“true”
       android:text=“@string/take_picture” />

</RelativeLayout>

Our CameraActivity.java – This code does almost all the operations from starting the device camera to saving the image to specified directory.

package com.example.camerahelper;
import java.io.File;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;

public class CameraActivity extends Activity {

    private static final String LOG_TAG = “CameraActivity.java”;
    private static final int IMAGE_CAPTURE = 0;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);

        try {

            // intent to start device camera
            Intent intent = new Intent(“android.media.action.IMAGE_CAPTURE”);

            // you can also create your own filename or path
            String fileName = “codeofaninja_app”;

            // where do you want to save the images
            String path = Environment.getExternalStorageDirectory() + “/”
                    + fileName + “.jpg”;

            File file = new File(path);

            // if the file name already exists, append __x on the file name
            int x = 2;
            while (file.exists()) {

                path = Environment.getExternalStorageDirectory() + “/”
                        + fileName + “__” + x + “.jpg”;
                file = new File(path);

                x++;
            }

            Uri outputFileUri = Uri.fromFile(file);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);

            // 0, this code will be returned in onActivityResult() when the
            // activity exits.
            startActivityForResult(intent, 0);

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

    }

    // activity exits
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        try {
            if (requestCode == IMAGE_CAPTURE) {
                if (resultCode == RESULT_OK) {

                    Log.v(LOG_TAG, “Picture taken.”);

                    // delete last image from dcim
                    if(!deleteLastSavedDcimImage()){
                        Log.v(LOG_TAG,“Unable to delete last saved image in /Camera/DCIM/”);
                    }

                    // ask if the user want’s to take another picture
                    takeAnother();

                } else {
                    // you can specify any message here
                    // or just remove it
                    Toast.makeText(getBaseContext(),
                            “Error: Result code is not RESULT_OK.”,
                            Toast.LENGTH_SHORT).show();

                }
            } else {
                // you can specify any message here
                // or just remove it
                Toast.makeText(getBaseContext(),
                        “Error: Request code is not IMAGE_CAPTURE.”,
                        Toast.LENGTH_SHORT).show();
            }

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

    @Override
    public void onBackPressed() {
        CameraActivity.this.finish();
    }

    public void takeAnother() {
        try {

            new AlertDialog.Builder(this).setTitle(“The Code Of A Ninja”)
                    .setMessage(“Do you want to take another picture?”)
                    .setPositiveButton(“YES”, new OnClickListener() {
                        public void onClick(DialogInterface arg0, int arg1) {
                            arg0.dismiss();

                            Intent nextActivity = new Intent(
                                    CameraActivity.this, CameraActivity.class);
                            CameraActivity.this.finish();
                            startActivity(nextActivity);

                        }
                    })

                    .setNegativeButton(“NO”, new OnClickListener() {
                        public void onClick(DialogInterface arg0, int arg1) {

                            arg0.dismiss();

                            Toast.makeText(CameraActivity.this,
                                    “Done taking picture.”, Toast.LENGTH_LONG)
                                    .show();

                            // go to main activity
                            CameraActivity.this.finish();

                        }
                    }).show();

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

    // since our code also saves the taken images to DCIM/Camera folder of the
    // device, we have to delete it there so that the image will be saved
    // only to the directory we have specified.
    private boolean deleteLastSavedDcimImage() {

        Log.v(LOG_TAG, “Deleting late image from DCIM.”);

        boolean success = false;

        try {

            // list the images in the device /DCIM/Camera directory
            File[] images = new File(Environment.getExternalStorageDirectory()
                    + “/DCIM/Camera”).listFiles();
            File lastSavedImage = images[0];
            int imagesLen =  images.length;
            
            //loop and check for the last modified image to get the last save image
            for (int i = 1; i < imagesLen; ++i) {
                if (images[i].lastModified() > lastSavedImage.lastModified()) {
                    lastSavedImage = images[i];
                }
            }

            //then delete the last saved image
            success = new File(lastSavedImage.toString()).delete();

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

        return success;
    }
}

Our res/layout/camera.xml code – XML I used for our CameraActivity.java activity

<?xml version=“1.0″ encoding=“utf-8″?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
   android:layout_width=“fill_parent”
   android:layout_height=“fill_parent”
   android:orientation=“vertical” >
    <TextView
       android:id=“@+id/textView1″
       android:layout_width=“wrap_content”
       android:layout_height=“wrap_content”
       android:text=“” >
    </TextView>

</LinearLayout>

The AndroidManifest.xml code – This will give us permission to use the device camera hardware.

<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
   package=“com.example.camerahelper”
   android:versionCode=“1″
   android:versionName=“1.0″ >
    <uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE” />
    <uses-permission android:name=“android.permission.CAMERA” />

    <uses-feature android:name=“android.hardware.camera” />
    <uses-feature android:name=“android.hardware.camera.autofocus” />

    <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>
        <activity android:name=“.CameraActivity” >
        </activity>
    </application>

</manifest>

Some output screenshots:

11

22

33