Archive

Posts Tagged ‘database’

Insert image to database

June 25, 2011 7 comments

In order to insert an image into SQLite database, you might need to use BLOB type, which stores binary data (it is, byte array).

Creating a database table:

CREATE TABLE tbl_image (
    _id INTEGER PRIMARY KEY AUTOINCREMENT,
    image_data BLOB
);

– Before inserting into database, you need to convert your BItmap image into byte array first then apply it using database query.

Please look at my previous post on “SQLite on Android” and “Create and Use custom Content Provider” for references.

For example, when I insert image using Database adapter:

	public long insert(byte[] image) {
		return mDb.insert(TABLE_NAME, null, createContentValues(image));
	}

	private ContentValues createContentValues(byte[] image) {
		ContentValues cv = new ContentValues();
		cv.put(COL_DATA, image);
		return cv;
	}

– When retrieving from database, you certainly have a byte array of image, what you need to do is to convert byte array back to original image. So, you have to make use of BitmapFactory to decode.

This is how I do encoding and decoding between byte array and bitmap:

package pete.android.study;

import java.io.ByteArrayOutputStream;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;

public class Utilities {

	// convert from bitmap to byte array
	public static byte[] getBytes(Bitmap bitmap) {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		bitmap.compress(CompressFormat.PNG, 0, stream);
		return stream.toByteArray();
	}

	// convert from byte array to bitmap
	public static Bitmap getImage(byte[] image) {
		return BitmapFactory.decodeByteArray(image, 0, image.length);
	}
}

This is the sample project in which will insert an image to database and display to screen after querying it.

Sample Project

Sample Project

Get project here: Browse Sample Project

Well, hope you like it!

 

Cheers,

Pete Houston

Categories: Tutorials Tags: , , ,

Load SQLite database on emulator


Sometimes you might need to check out your database inside emulator with or w/o coding.

1. Launch emulator.

2. Open Command Prompt and access location of ‘adb.exe

3. Type as following

[C:\Program Files\Android\android-sdk\platform-tools]adb -e shell
#

4. ADB Shell is prompted. Now just located your sqlite database. Eg: I have my package ‘pete.android.study‘, then my database will be put at:

data/data/pete.android.study/databases
Load Shell

Load Shell

5. Now I just need to load my database to use:

# sqlite3 user_db
SQLite3 Shell Prompt

SQLite3 Shell Prompt

Hope you enjoy it!

Cheers,
Pete Houston

Categories: Tutorials Tags: , , ,

SQLite on Android – Part III (The Final)

June 16, 2011 7 comments

Ok! Now you probably get the idea of using SQLite on Android. Let’s move on to complete our application as usual.

 

G – Sketching the Layout

As usual, we create two layouts: one for list item, one for main display.

1. List Item Layout: (layout_list_item.xml)

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

  <LinearLayout
  	android:orientation="horizontal"
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  >
  	<TextView
  		android:id="@+id/txtName"
  		android:layout_width="wrap_content"
  		android:layout_height="wrap_content"
  		android:layout_weight="1"
  		android:textStyle="bold"
  		android:textColor="@android:color/white"
  	/>
  	<TextView
  		android:id="@+id/txtAge"
  		android:layout_width="wrap_content"
  		android:layout_height="wrap_content"
  		android:layout_weight="1"
  		android:layout_marginRight="5dip"
  		android:paddingRight="10dip"
  		android:gravity="right"
  		android:textStyle="italic"
  	/>
  </LinearLayout>

  <TextView
  	android:id="@+id/txtCity"
  	android:layout_width="fill_parent"
  	android:layout_height="wrap_content"
  	android:singleLine="true"
  	android:gravity="left"
  	android:textStyle="italic"
  />

</LinearLayout>

2. Main Layout: (layout_main.xml)

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

	<ListView
		android:id="@+id/listUsers"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
	/>

</LinearLayout>

H – Class Diagram: On the Idea

Class Diagram - On the Idea

Class Diagram - On the Idea

Hang on! What are the things called “UserInfoCreator” and “ViewHolder“?

Eh oh, “UserInfoCreator” is the class designed for creating records for database and wrapping around UserDbAdapter. I’m just trying to minimize work on MainActivity.

About “ViewHolder”, it’s just a pattern to cache memory when inflating layout. You might need to refer to my other post on Design Pattern – ViewHolder.

 

I – From Design to Coding (w/ Passion)

1. UserInfo: (UserInfo.java)

package pete.android.study;

public class UserInfo {
	// fields
	private int mId;
	private String mName;
	private int mAge;
	private String mCity;

	/*
	 * constructor
	 */
	public UserInfo(int id, String name, int age, String city) {
		mId = id;
		mName = name;
		mAge = age;
		mCity = city;
	}

	/*
	 * set user id
	 */
	public void setID(int id) {
		mId = id;
	}

	/*
	 * get user id
	 */
	public int getID() {
		return mId;
	}

	/*
	 * set user name
	 */
	public void setName(String name) {
		mName = name;
	}

	/*
	 * get user name
	 */
	public String getName() {
		return mName;
	}

	/*
	 * set user age
	 */
	public void setAge(int age) {
		mAge = age;
	}

	/*
	 * get user age
	 */
	public int getAge() {
		return mAge;
	}

	/*
	 * set user city
	 */
	public void setCity(String city) {
		mCity = city;
	}

	/*
	 * get user city
	 */
	public String getCity() {
		return mCity;
	}
}

2. UserInfoAdapter: (UserInfoAdapter.java)

package pete.android.study;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class UserInfoAdapter extends BaseAdapter {

	// private objects
	private List<UserInfo> mListUserInfo;
	private LayoutInflater mInflater;

	/*
	 * constructor
	 */
	public UserInfoAdapter(Context c, List<UserInfo> list) {
		mListUserInfo = list;
		// create layout inflater
		mInflater = LayoutInflater.from(c);
	}

	/*
	 * (non-Javadoc)
	 * @see android.widget.Adapter#getCount()
	 */
	@Override
	public int getCount() {
		return mListUserInfo.size();
	}

	/*
	 * (non-Javadoc)
	 * @see android.widget.Adapter#getItem(int)
	 */
	@Override
	public Object getItem(int position) {
		return mListUserInfo.get(position);
	}

	/*
	 * (non-Javadoc)
	 * @see android.widget.Adapter#getItemId(int)
	 */
	@Override
	public long getItemId(int position) {
		return position;
	}

	/*
	 * (non-Javadoc)
	 * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		// get view reference
		View view = convertView;
		// if null
		if(view == null) {
			// inflate new layout
			view = mInflater.inflate(R.layout.layout_list_item, null);
			// create a holder
			ViewHolder holder = new ViewHolder();
			// find controls
			holder.txtName = (TextView)view.findViewById(R.id.txtName);
			holder.txtAge = (TextView)view.findViewById(R.id.txtAge);
			holder.txtCity = (TextView)view.findViewById(R.id.txtCity);
			// set data structure to view
			view.setTag(holder);
		}

		// get selected user info
		UserInfo userInfo = mListUserInfo.get(position);
		// if not null
		if(userInfo != null) {
			// query data structure
			ViewHolder holder = (ViewHolder)view.getTag();
			// set data to display
			holder.txtName.setText(userInfo.getName());
			holder.txtAge.setText("(" + String.valueOf(userInfo.getAge()) + ")");
			holder.txtCity.setText(userInfo.getCity());
		}

		// return view
		return view;
	}

	/*
	 * @class ViewHolder
	 * to hold data structure on view with user info
	 */
	static class ViewHolder {
		private TextView txtName;
		private TextView txtAge;
		private TextView txtCity;
	}
}

3. UserInfoCreator: (UserInfoCreator.java)

package pete.android.study;

import java.util.List;

import android.content.Context;

public class UserInfoCreator {
	// db adapter
	private UserDbAdapter mDbAdapter;

	/*
	 * constructor
	 */
	public UserInfoCreator(Context c) {
		mDbAdapter = new UserDbAdapter(c);
	}

	/*
	 * open DBAdapter connection
	 */
	public void open() {
		mDbAdapter.open();
	}

	/*
	 * insert random data
	 */
	public void insert() {
    	mDbAdapter.insertUser("Pete Houston", 29, "Seoul, South Korea");
    	mDbAdapter.insertUser("Kelly Hooker", 22, "London, England");
    	mDbAdapter.insertUser("Jung Ha Lee", 25, "Pusan, South Korea");
    	mDbAdapter.insertUser("Elly Nguyen", 20, "Hanoi, Vietnam");
    	mDbAdapter.insertUser("Hana Kaemi", 26, "Kyoto, Japan");
    	mDbAdapter.insertUser("Jenya Kavroski", 19, "Leningrad, Russia");
	}

	/*
	 * query all user info from db
	 */
	public List<UserInfo> queryAll() {
		return mDbAdapter.fetchAllUsers();
	}

	/*
	 * close connection
	 */
	public void close() {
		mDbAdapter.close();
	}
}

4. MainActivity: (MainActivity.java)

package pete.android.study;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
	// TAG for LogCat
    public static final String TAG = "SQLiteDebug";
    // list view control
	private ListView mListUserInfo;

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

        // load list view control
        mListUserInfo = (ListView)findViewById(R.id.listUsers);

        // create data creator
        UserInfoCreator creator = new UserInfoCreator(this);
        // open connection
        creator.open();
        // insert data
        creator.insert();
        // add data to list view through adapter
        mListUserInfo.setAdapter(new UserInfoAdapter(this, creator.queryAll()));
        // close connection
        creator.close();

    }

}

J – Note

– It’s simple, yet complicated!

 

K – Get the Project by Pete

From now on, I’ll use GoogleCode for hosting my projects. So please access it through my given link!

-> Browse: SQLiteStudy by Pete on GoogleCode

 

L – Final Words

– Have you learned something good from here?

– Try to practice until you master SQLite on Android

– I’ll always be here to support any of you, I’ll try my best 🙂

 

Hope you enjoy this SQLite series!

 

Cheers,

Pete Houston

Categories: Tutorials Tags: , , ,

SQLite on Android – Part II

June 16, 2011 1 comment

In my previous, I’ve introduced you the idea and the basic mechanisms of SQLite on Android, so now, I will guide you to create the actual project.

 

E – Create the Project

Project Name: SQLite Study

Build Target: Android 2.3.3

Application Name: SQLite Study

Package Name: pete.android.study

Create Activity: MainActivity

Min SDK Version: 10

 

F – The Children Born: The Data Handling Couple

– First, let’s name them as: UserDbHelper (which inherits from SQLiteOpenHelper) and UserDbAdapter.

1. UserDbHelper: (UserDbHelper.java)

– What shall we do with this one? According to the Android documentation, we need to override two methods ‘onCreate’ and ‘onUpgrade()‘ for our own implemention. That’s all of it!

package pete.android.study;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class UserDbHelper extends SQLiteOpenHelper {

	// declare constants fields
	private static final String DB_NAME = "user_db";
	private static final int DB_VERSION = 1;

	// declared constant SQL Expression
	private static final String DB_CREATE =
		"CREATE TABLE tbl_info ( " +
		"_id integer PRIMARY KEY AUTOINCREMENT, " +
		"name text NOT NULL, " +
		"age integer NOT NULL, " +
		"city text NOT NULL" +
		");";

	private static final String DB_DESTROY =
		"DROP TABLE IF EXISTS tbl_info";

	/*
	 * constructor
	 */
	public UserDbHelper(Context context) {
		super(context, DB_NAME, null, DB_VERSION);
	}

	/*
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(DB_CREATE);
	}

	/*
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL(DB_DESTROY);
		onCreate(db);
	}

}

Note: the database is not actually created after ‘getReadableDatabase()‘ or ‘getWriteableDatabase()‘ is called.
2. UserDbAdapter: (UserDbAdapter.java)

The first things we need to implement is to call either ‘getWriteableDatabase()‘ or ‘getReadableDatabase()’ to create the actual database, in which will return a SQLiteDatabase object, that we will use directly to manipulate database.

So far so good, we need to have two field of SQLiteDatabase  and UserDbHelper objects at least. Also, we need a Context to define our UserDbHelper as described in its constructor.

Have a look at Android documentation on SQLiteDatabase class to find our needs.

– Let see what we need to do in this class. First, we need to provide some ways to

+ open the connection to database (SQLiteDatabase::getWriteableDatabase())

+ insert a new record to database (SQLiteDatabase::insert())

+ update a record in database (SQLiteDatabase::update())

+ delete a record in database (SQLiteDatabase::delete())

+ select one single record from database (SQLiteDatabase::query())

+ select all records from database (SQLiteDatabase::query())

+ close connection when done (SQLiteOpenHelper::close())

Since the connection to SQLiteDatabase is initiated through UserDbHelper, which inherits from SQLiteHelper, the UserDbHelper object is the one handling the connection, open or close.

Here the implementation:

package pete.android.study;

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

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

public class UserDbAdapter {

	// declare database fields
	public static final String TBL_INFO = "tbl_info";
	public static final String COL_ID = "_id";
	public static final String COL_NAME = "name";
	public static final String COL_AGE = "age";
	public static final String COL_CITY = "city";

	// projection on all columns
	private static final String[] PROJECTION_ALL = new String[] {
		COL_ID, COL_NAME, COL_AGE, COL_CITY
	};

	// query output type
	public static final int QUERY_TYPE_STRING_ARRAY = 0x01;
	public static final int QUERY_TYPE_USERINFO_OBJ = 0x02;

	// declared fields
	private Context mContext;
	private SQLiteDatabase mDb;
	private UserDbHelper mDbHelper;

	/*
	 * constructor
	 */
	public UserDbAdapter(Context c) {
		mContext = c;
	}

	/*
	 * open database connection
	 */
	public UserDbAdapter open() throws SQLException {
		mDbHelper = new UserDbHelper(mContext);
		mDb = mDbHelper.getWritableDatabase();
		return this;
	}

	/*
	 * close database connection
	 */
	public void close() {
		mDbHelper.close();
	}

	/*
	 * insert a record to db
	 */
	public long insertUser(String name, int age, String city) {
		return mDb.insert(TBL_INFO, null, createContentValues(name, age, city));
	}

	/*
	 * update a record to db
	 */
	public long updateUser(int id, String name, int age, String city) {
		return mDb.update(TBL_INFO, createContentValues(name, age, city), COL_ID + "=" + id, null);
	}

	/*
	 * delete a record from db
	 */
	public long deleteUser(int id) {
		return mDb.delete(TBL_INFO, COL_ID + "=" + id, null);
	}

	/*
	 * query all records
	 */
	public List<UserInfo> fetchAllUsers() {
		// get query cursor
		Cursor queryCursor = mDb.query(TBL_INFO, PROJECTION_ALL, null, null, null, null, null);
		// just return null if cursor null
		if(queryCursor == null) {
			Log.d(MainActivity.TAG, "UserDbAdapter.fetchAllUsers(): queryCursor = null ");
			return null;
		}
		// init list to hold user info
		List<UserInfo> listUsers = new ArrayList<UserInfo>();
		// set cursor to the first element
		queryCursor.moveToFirst();
		// if cursor is not the last element
		while(queryCursor.isAfterLast() == false) {
			// add new user info
			listUsers.add(new UserInfo(
					// get user id from cursor
					queryCursor.getInt(queryCursor.getColumnIndexOrThrow(COL_ID)),
					// get user name from cursor
					queryCursor.getString(queryCursor.getColumnIndexOrThrow(COL_NAME)),
					// get user age from cursor
					queryCursor.getInt(queryCursor.getColumnIndexOrThrow(COL_AGE)),
					// get user city from cursor
					queryCursor.getString(queryCursor.getColumnIndexOrThrow(COL_CITY))
				)
			);
			// move cursor to next item
			queryCursor.moveToNext();
		}
		// check if cursor is still opened and not null
		if(queryCursor != null && !queryCursor.isClosed()) {
			// close it to avoid memory leak
			queryCursor.close();
		}
		Log.d(MainActivity.TAG, "UserDbAdapter.fetchAllUsers(): listUsers.size() = " + listUsers.size());
		// return user list
		return listUsers;
	}

	/*
	 * query one record
	 */
	public Object fetchSingleUser(int id, int type) {
		// query a cursor on identified user
		Cursor c = mDb.query(true, TBL_INFO, PROJECTION_ALL, COL_ID + "=" + id, null, null, null, null, null);
		// return null if no record avaiable
		if(c == null) {
			return null;
		}

		Object objOut = null;

		if(type == QUERY_TYPE_STRING_ARRAY) {
			// create array to hold user info
			String[] user_info = new String[4];
			user_info[0] = String.valueOf(id);
			user_info[1] = c.getString(c.getColumnIndexOrThrow(COL_NAME));
			user_info[2] = c.getString(c.getColumnIndexOrThrow(COL_AGE));
			user_info[3] = c.getString(c.getColumnIndexOrThrow(COL_CITY));
			objOut = user_info;
		} else {
			// create UserInfo object
			UserInfo user_info = new UserInfo(
					id,
					c.getString(c.getColumnIndexOrThrow(COL_NAME)),
					c.getInt(c.getColumnIndexOrThrow(COL_AGE)),
					c.getString(c.getColumnIndexOrThrow(COL_CITY))
			);
			objOut = user_info;
		}
		// close cursor
		c.close();

		// return user info
		return objOut;
	}

	/*
	 * create ContentValues object to use for db transaction
	 */
	private ContentValues createContentValues(String name, int age, String city) {
		// init a ContentValues object
		ContentValues cv = new ContentValues();
		// put data
		cv.put(COL_NAME, name);
		cv.put(COL_AGE, age);
		cv.put(COL_CITY, city);
		// return object
		return cv;
	}
}

After reading above code, you may wonder:

+ Why do I return a list of UserInfo in fetchAllUser()? The answer is, as I mentioned in previous post (Part I), I will create a list view to display user information queried from database, so I create an entity class named ‘UserInfo‘ to hold every piece of user info. In order to avoid working around with database outside of this UserDbAdapter, I’ve just extracted all data from Cursor to create all user information and return into a list. Therefore, the other classes don’t need to worry about extracting data from Cursor. It’s very convenient!

+ Why do I return the Object in fetchSingleUser()? The answer is, in case the other class wants to have an array of String or prefer UserInfo object, then I just need to return Object to avoid the conversion between string array and UserInfo. Well, it’s flexible my way!

Just think it simple! Those methods, insert() – query() – delete() – update(), are wrappers around SQL query expressions, where you need to suitable input parameters to execute properly.

For insert() and update(), you need to use a ContentValues object to store all keys and values which would be passed as parameters. As you see in above code, I don’t pack column ‘_id‘ in ContentValues, because _id is created as AUTOINCREMENT, so I don’t need to. For convenience, I’ve created a private method ‘createContentValue()‘ to pack all things need to be inserted or updated.

When update(), you need to specify which record, therefore, the parameter ‘ COL_ID + “=” + id‘ is needed for.Similarly working while delete(), just specify row id to be deleted is enough.

The query() will return a Cursor object which point to a list structure (I guess @@) of results found. Before extracting data from a Cursor, remember to always call ‘moveToFirst()‘ to set its pointer at beginning of the list. Otherwise, you would receive unexpected results.Cursor object will point to each row of the table, you need to use proper methods to get data from each column of the row.Eg.: Cursor::getInt(), Cursor::getString(), Cursor::getExtras()

In order to get column index from column name, use ‘Cursor::getColumnIndex()‘ or ‘Cursor::getColumnIndexOrThrow()‘ if  you’re not sure about column name is correct or not.

You might want to refer to Android documentation on Cursor.

If Cursor points to many records, then just call ‘moveToNext()‘ to point to next row.

 

That’s done for part II!

Take some coffee and move around … wait for the final part!

 

Cheers,

Pete Houston

Categories: Tutorials Tags: , , ,

SQLite on Android – Part I

June 16, 2011 2 comments

This is gonna be a very very long tutorials about SQLite on Android; I will guide you how to use and apply to make one simple application, like this:

Screenshot

Screenshot

The application is simple, create a database, insert some records, during load screen, all records will be queried and displayed to a list view like the image above.

A – Requirements

– You probably need to know something before to get straight forward into this tutorial:

1. Some Android basic operation: like handling list view, custom view display, layout & user-interface presentation…which are all mentioned in my previous posts. Make sure you have known or read about it, you MUST understand the mechanism how it works. If not, try to re-read, re-code and re-think until you understand and make it your own.

2. Know how to work around with SQLite, just a bit basic like: creating database, delete database, creating tables, deleting tables, select/insert/update/delete … Use SQLite version 3, because it is implemented on Android.

That’s all you need before getting started!

B – Data Modeling: On the Idea

Since the app we’re going to create is very simple, the modeling is absolutely simple.

Data Modeling - On the Idea

Data Modeling - On the Idea

We shall need to create a SQLite database named ‘user_db‘ which holds one single table ‘tbl_info‘ to contain user information.

C – Revised on SQLite Query Expressions

Ok! A bit practice on SQLite query expression that we will use:

1. to create table ‘tbl_info

CREATE TABLE tbl_info (
    _id integer PRIMARY KEY AUTOINCREMENT,
    name text NOT NULL,
    age integer NOT NULL,
    city text NOT NULL
);

2. to delete table ‘tbl_info

DROP TABLE IF EXISTS tbl_info;

3. to insert a record into table ‘tbl_info

INSERT INTO tbl_info(name, age, city) VALUES ("Pete Houston", 29, "Seoul, South Korea");

4. to update a record into table ‘tbl_info
Eg: to update age from 29 to 32 for user having ‘_id = 1’:

UPDATE tbl_info SET age=32 WHERE _id=1;

5. to delete a record from table ‘tbl_info

DELETE FROM tbl_info WHERE _id=1;

6. to delete all records

DELETE * FROM tbl_info;

Well, that might be enough for now!
Have you understand a bit about SQLite upto now?

D – The Couple Handler

Generally, in a using-SQLite Android application, you need to design two classes in such a purposes: one class for handling database physically (like creating database files..), and the other is for logical handling (like execute SQL query expressions…).

1. The one for handling database physically is always inherited from class ‘SQLiteOpenHelper‘ (android.database.sqlite)

A helper class to manage database creation and version management.

You create a subclass implementing onCreate(SQLiteDatabase), onUpgrade(SQLiteDatabase, int, int) and optionally onOpen(SQLiteDatabase), and this class takes care of opening the database if it exists, creating it if it does not, and upgrading it as necessary. Transactions are used to make sure the database is always in a sensible state.

This class makes it easy for ContentProvider implementations to defer opening and upgrading the database until first use, to avoid blocking application startup with long-running database upgrades.

That’s what is said in Android documentation.

Therefore, when you inherit your class from SQLiteOpenHelper, you need to override the two provided methods.

	@Override
	public void onCreate(SQLiteDatabase db) {
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}

– ‘onCreate‘ will be called when database is created.
– ‘onUpdate’ will be called when database version is changed, in which the old database file is deleted and the new one is created instead.

(That’s the reason why I called this ‘handling database physcally‘ if you ever wonder!)

– In common, this class name has suffix ‘Helper‘ to determine inheritance from SQLiteOpenHelper.

2. The other class provides the mechanism to handling database logically: like insert records, query records, delete records…Commonly, the class name has suffix ‘Adapter‘ to determine its job, just similar ListAdapter, BaseAdapter…or whatever adapter which provide such mechanisms for handling data logically.

 

It’s quite long for a tutorial, so I break up here.

Wait for my next part

 

Cheers,

Pete Houston

 

Categories: Tutorials Tags: , , ,