You are on page 1of 27

Data Storage

Android provides several options for you to save persistent application data. The solution you
choose depends on your specific needs, such as whether the data should be private to your
application or accessible to other applications (and the user) and how much space your data
requires.

Your data storage options are the following:

Shared Preferences

Store private primitive data in key-value pairs.

Internal Storage

Store private data on the device memory.

External Storage

Store public data on the shared external storage.

SQLite Databases

Store structured data in a private database.

Network Connection

Store data on the web with your own network server.

Android provides a way for you to expose even your private data to other applications with a
content provider. A content provider is an optional component that exposes read/write access to
your application data, subject to whatever restrictions you want to impose. For more information
about using content providers, see the Content Providers documentation.
SQLite

SQLite is an Open Source Database which is embedded into Android.

SQLite supports standard relational database features like SQL syntax, transactions and
prepared statements. In addition

it requires only little memory at runtime (approx. 250 KByte).

SQLite supports the data types TEXT (similar to String in Java), INTEGER (similar to long
in Java) and REAL (similar to double in Java). All other types must be converted into one of
these fields before saving them in the database. SQLite itself does not validate if the types
written to the columns are actually of the defined type, you can write an integer into a string
column.

SQLite is available on every Android device. Using an SQLite database in Android does not
require any database setup or administration. We can specify the SQL for working with the
database and the database is automatically managed for us.

Working with databases can be slow. Therefore is it recommended to perform these task in the
background, for example via an AsyncTask.

If your application creates an database this database is saved in the directory


DATA/data/APP_NAME/databases/FILENAME. DATA is the path which
Environment.getDataDirectory() returns, APP_NAME is your application name and FILENAME
is the name you give the database during creation. Environment.getDataDirectory() usually
return the SD card as location.

A SQLite database is private to the application which creates it. If you want to share data
with other applications you can use a ContentProvider. If data is not shared it typically
easier to work directly with the database.
public class
SQLiteDatabase
extends SQLiteClosable

java.lang.Object
android.database.sqlite.SQLiteClosable
android.database.sqlite.SQLiteDatabase

Class Overview

Exposes methods to manage a SQLite database.

SQLiteDatabase has methods to create, delete, execute SQL commands, and perform other
common database management tasks.

See the Notepad sample application in the SDK for an example of creating and managing a
database.

Database names must be unique within an application, not across all applications.

Localized Collation - ORDER BY

In addition to SQLite's default BINARY collator, Android supplies two more, LOCALIZED, which
changes with the system's current locale if you wire it up correctly (XXX a link needed!), and
UNICODE, which is the Unicode Collation Algorithm and not tailored to the current locale.

.
.
.
.
package
android.database.sqlite

Contains the SQLite database management classes that an application would use to manage its
own private database.

Applications use these classes to manage private databases. If creating a content provider, you
will probably have to use these classes to create and manage your own database to store content.
See Content Providers to learn the conventions for implementing a content provider. See the NotePadProvider class
in the NotePad sample application in the SDK for an example of a content provider. Android ships with SQLite
version 3.4.0

If you are working with data sent to you by a provider, you will not use these SQLite classes, but
instead use the generic android.database classes.

Android ships with the sqlite3 database tool in the tools/ folder. You can use this tool to browse
or run SQL commands on the device. Run by typing sqlite3 in a shell window.

Interfaces

SQLiteCursorDriver A driver for SQLiteCursors that is used to create them and gets
notified by the cursors it creates on significant events in their
lifetimes.
SQLiteDatabase.CursorFactor Used to allow returning sub-classes of Cursor when calling
y query.
SQLiteTransactionListener A listener for transaction events.

Classes

SQLiteClosable An object created from a SQLiteDatabase that can be closed.

SQLiteCursor A Cursor implementation that exposes results from a query on a


SQLiteDatabase.
SQLiteDatabase Exposes methods to manage a SQLite database.

SQLiteOpenHelper A helper class to manage database creation and version management.

SQLiteProgram A base class for compiled SQLite programs.

SQLiteQuery A SQLite program that represents a query that reads the resulting rows
into a CursorWindow.
SQLiteQueryBuilde This is a convience class that helps build SQL queries to be sent to
r SQLiteDatabase objects.

SQLiteStatement A pre-compiled statement against a SQLiteDatabase that can be reused.

Exceptions
SQLiteAbortException An exception that indicates that the SQLite
program was aborted.
SQLiteAccessPermException This exception class is used when sqlite
can't access the database file due to lack of
permissions on the file.
SQLiteBindOrColumnIndexOutOfRangeExceptio Thrown if the the bind or column
n parameter index is out of range
SQLiteBlobTooBigException
SQLiteCantOpenDatabaseException
SQLiteConstraintException An exception that indicates that an integrity
constraint was violated.
SQLiteDatabaseCorruptException An exception that indicates that the SQLite
database file is corrupt.
SQLiteDatabaseLockedException Thrown if the database engine was unable
to acquire the database locks it needs to do
its job.
SQLiteDatatypeMismatchException
SQLiteDiskIOException An exception that indicates that an IO error
occured while accessing the SQLite
database file.
SQLiteDoneException An exception that indicates that the SQLite
program is done.
SQLiteException A SQLite exception that indicates there
was an error with SQL parsing or
execution.
SQLiteFullException An exception that indicates that the SQLite
database is full.
SQLiteMisuseException This error can occur if the application
creates a SQLiteStatement object and
allows multiple threads in the application
use it at the same time.
SQLiteOutOfMemoryException
SQLiteReadOnlyDatabaseException
SQLiteTableLockedException
2. Android Architecture

2.1. Packages

The package android.database contains all general classes for working with databases.
android.database.sqlite contains the SQLite specific classes.

2.2. SQLiteOpenHelper

To create and upgrade a database in your Android application you usually subclass
SQLiteOpenHelper. In this class you need to override the methods onCreate() to create the
database and onUpgrade() to upgrade the database in case of changes in the database
schema. Both methods receive an SQLiteDatabase object which represents the database.

SQLiteOpenHelper provides the methods getReadableDatabase() and


getWriteableDatabase() to get access to an SQLiteDatabase object which allows database
access either in read or write mode.

For the primary key of the database tables you should always use the identifier _id as some of
Android functions rely on this standard.

A best practice is to create per table a separate class which define static onCreate() and
onUpdate() methods. These methods are then called in the corresponding methods of
SQLiteOpenHelper . This way your implementation of SQLiteOpenHelper will not get to large
even if you have several tables.

2.3. SQLiteDatabase

SQLiteDatabase is the base class for working with an SQLite database in Android and
provides methods to open, query, update and close the database. More specifically
SQLiteDatabase provides the insert(), update() and delete() methods. The execSQL() method
allows to execute directly SQL. The object ContentValues allow to define key/values for insert
and update. The key is the column and the value is the value for this column.

Queries can be created via the method rawQuery() which accepts SQL or query() which
provides an interface for specifying dynamic data or SQLiteQueryBuilder.

For example to run a rawQuery() you can do the following:

Cursor cursor = getReadableDatabase().rawQuery("select * from todo where _id = ?", new


String[] { id });
The method query() has the following parameters.

String dbName - The table name to compile the query against


int[] columnNames - A list of which columns to return. Passing null will return all
columns.
String whereClause - Filter for the selection of data without the "WHERE" clause, null
will select all
selectionArgs You may include ?s in the whereClause, which will be replaced by the
values from selectionArgs.
String[] groupBy - A filter declaring how to group rows, null will cause the rows to
not be grouped.
String[] having - Filter for the goups, null means no filter
String[] orderBy - row which will be used to order the data, null means no ordering

If all data should be selected you can pass null as the where clause. The where clause is specified
without where, for example _id=19 and summary=? . If several values are required via ? you
pass them in the valuesForWhereClause array to the query. In general if something is not
required you can pass null,
e.g. for the group by clause.
For example to run a query() you can do the following:

return database.query(DATABASE_TABLE,
new String[] { KEY_ROWID, KEY_CATEGORY, KEY_SUMMARY,
KEY_DESCRIPTION },
null, null, null, null, null);

2.4. Cursor

A query returns always a Cursor. A Cursor represents the result of a query and basically points
always to one row of the database. This way Android can buffer the results efficiently as it does
not have to load all data into memory.

To get the number of elements use the method getCount(). To move between individual data
rows, you can use the methods moveToFirst() and moveToNext(). Via the method isAfterLast()
you can check if there is still some data.
To access data Cursor provides typed get methods, e.g. getLong(columnIndex),
getString(columnIndex) whereby the columnIndex is the number of the column we are
accessing.

A Cursor can be directly used via the SimpleCursorAdapter in ListViews.

2.5. ListViews, ListActivities and SimpleCursorAdapter

ListViews are views (widgets) which makes it easy to display a list of elements. ListActivities
are specialized Activities which make the usage of ListViews easier. This tutorial will use
ListActivities but not look into the details of them. Please see
http://www.vogella.de/articles/AndroidListView/article.html for an introduction into ListViews
and ListActivities.

To work with databases and ListViews you can use the SimpleCursorAdapter. The
SimpleCursorAdapter allows to set a layout for each row of the ListViews. You also define an
array column names and an array of view Ids. The adapter will map the columns to the views
based on the Cursor passed to it.

3. Command line interface for SQLite

It is possible to access an SQLite database on the emulator or a rooted device via the command
line. For this use adb shell to connect to the device and the command "sqlite3" to connect to an
database
1. Preparing the SQLite database file.

Assuming you already have your sqlite database created, we need to do some modifications to it.
If you don't have a sqlite manager I recommend you to download the opensource SQLite
Database Browser available for Win/Linux/Mac.

Open your database and add a new table called "android_metadata", you can execute the
following SQL statement to do it:

CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US')

Now insert a single row with the text 'en_US' in the "android_metadata" table:

INSERT INTO "android_metadata" VALUES ('en_US')

Then, it is necessary to rename the primary id field of your tables to "_id" so Android will know
where to bind the id field of your tables.
You can easily do this with SQLite Database Browser by pressing the edit table button ,
then selecting the table you want to edit and finally selecting the field you want to rename.

After renaming the id field of all your data tables to "_id" and adding the "android_metadata"
table, your database it's ready to be used in your Android application.
Modified database

Note: in this image we see the tables "Categories" and "Content" with the id field renamed to
"_id" and the just added table "android_metadata".

2. Copying, opening and accessing your database in your Android application.

Now just put your database file in the "assets" folder of your project and create a Database
Helper class by extending the SQLiteOpenHelper class from the "android.database.sqlite"
package.

Make your DataBaseHelper class look like this:


public class DataBaseHelper extends SQLiteOpenHelper{

//The Android's default system path of your application database.


private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";

private static String DB_NAME = "myDBName";

private SQLiteDatabase myDataBase;

private final Context myContext;

/**
* Constructor
* Takes and keeps a reference of the passed context in order to access
to the application assets and resources.
* @param context
*/
public DataBaseHelper(Context context) {

super(context, DB_NAME, null, 1);


this.myContext = context;
}

/**
* Creates a empty database on the system and rewrites it with your own
database.
* */
public void createDataBase() throws IOException{

boolean dbExist = checkDataBase();

if(dbExist){
//do nothing - database already exist
}else{

//By calling this method and empty database will be created


into the default system path
//of your application so we are gonna be able to overwrite
that database with our database.
this.getReadableDatabase();

try {

copyDataBase();

} catch (IOException e) {

throw new Error("Error copying database");

}
}

/**
* Check if the database already exist to avoid re-copying the file each
time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){

SQLiteDatabase checkDB = null;

try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);

}catch(SQLiteException e){

//database does't exist yet.

if(checkDB != null){

checkDB.close();

return checkDB != null ? true : false;


}

/**
* Copies your database from your local assets-folder to the just created
empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{

//Open your local db as the input stream


InputStream myInput = myContext.getAssets().open(DB_NAME);

// Path to the just created empty db


String outFileName = DB_PATH + DB_NAME;

//Open the empty db as the output stream


OutputStream myOutput = new FileOutputStream(outFileName);

//transfer bytes from the inputfile to the outputfile


byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0){
myOutput.write(buffer, 0, length);
}

//Close the streams


myOutput.flush();
myOutput.close();
myInput.close();

}
public void openDataBase() throws SQLException{

//Open the database


String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);

@Override
public synchronized void close() {

if(myDataBase != null)
myDataBase.close();

super.close();

@Override
public void onCreate(SQLiteDatabase db) {

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

// Add your public helper methods to access and get content from the
database.
// You could return cursors by doing "return myDataBase.query(....)"
so it'd be easy
// to you to create adapters for your views.

That's it.
Now you can create a new instance of this DataBaseHelper class and call the createDataBase()
and openDataBase() methods. Remember to change the "YOUR_PACKAGE" to your
application package namespace (i.e: com.examplename.myapp) in the DB_PATH string.

...

DataBaseHelper myDbHelper = new DataBaseHelper();


myDbHelper = new DataBaseHelper(this);

try {

myDbHelper.createDataBase();

} catch (IOException ioe) {

throw new Error("Unable to create database");


}

try {

myDbHelper.openDataBase();

}catch(SQLException sqle){

throw sqle;

...
http://www.codeproject.com/KB/android/AndroidSQLite.aspx

Introduction

Android default Database engine is Lite.

SQLite is a lightweight transactional database engine that occupies a small amount of disk
storage and memory, so it's a perfect choice for creating databases on many mobile operating
systems such as Android, iOS.

Things to consider when dealing with SQLite:


1. Data type integrity is not maintained in SQLite, you can put a value of a certain data
type in a column of another datatype (put string in an integer and vice versa).
2. Referential integrity is not maintained in SQLite, there is no FOREIGN KEY
constraints or JOIN statements.
3. SQLite Full Unicode support is optional and not installed by default.

Now, we will create a simple database application to store employees data. the DB has:

Tables
1. Employees
2. Dept
Views
1. ViewEmps: to display employees and their relative departments.
Creating SQLite Database

By default, SQLite on Android does not have a management interface or an application to


create and manage databases from, so we're going to create the database ourselves by code.

First, we will create a class that handles all the operations required to deal with the database such
as creating the database, creating tables, inserting and deleting records and so on. The first step
is to create a class that inherits from SQLiteOpenHelper class. This class provides two
methods to override to deal with the database:

1. onCreate(SQLiteDatabase db): invoked when the database is created, this is where we


can create tables and columns to them, create views or triggers.

2. onUpgrade(SQLiteDatabse db, int oldVersion, int newVersion): invoked when we


make a modification to the database such as altering, dropping , creating new tables.

Our class will have the following members:

public class DatabaseHelper extends SQLiteOpenHelper {

static final String dbName="demoDB";


static final String employeeTable="Employees";
static final String colID="EmployeeID";
static final String colName="EmployeeName";
static final String colAge="Age";
static final String colDept="Dept";

static final String deptTable="Dept";


static final String colDeptID="DeptID";
static final String colDeptName="DeptName";

static final String viewEmps="ViewEmps";

The Constructor

public DatabaseHelper(Context context) {

super(context, dbName, null,33);


}

The constructor of the super class has the following parameters:


Context con: The context attached to the database
dataBaseName: The name of the database
CursorFactory: Sometimes, we may use a class that extends the Cursor class to
implement some extra validations or operations on the queries run on the database. In this
case, we pass an instance of CursorFactory to return a reference to our derived class to be
used instead of the default cursor. In this example, we are going to use the standard
Cursor Interface to retrieve results, so the CursorFactory parameter is going to be null.
Version: the version of the schema of the database. The constructor creates a new blank
database with the specified name and version.

Creating the Database


The first superclass method to override is onCreate(SQLiteDatabase db):

public void onCreate(SQLiteDatabase db) {


// TODO Auto-generated method stub

db.execSQL("CREATE TABLE "+deptTable+" ("+colDeptID+ " INTEGER PRIMARY KEY ,


"+ colDeptName+ " TEXT)");

db.execSQL("CREATE TABLE "+employeeTable+"


("+colID+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
colName+" TEXT, "+colAge+" Integer, "+colDept+"
INTEGER NOT NULL ,FOREIGN KEY ("+colDept+") REFERENCES
"+deptTable+" ("+colDeptID+"));");

db.execSQL("CREATE TRIGGER fk_empdept_deptid " +


" BEFORE INSERT "+
" ON "+employeeTable+

" FOR EACH ROW BEGIN"+


" SELECT CASE WHEN ((SELECT "+colDeptID+" FROM "+deptTable+"
WHERE "+colDeptID+"=new."+colDept+" ) IS NULL)"+
" THEN RAISE (ABORT,'Foreign Key Violation') END;"+
" END;");

db.execSQL("CREATE VIEW "+viewEmps+


" AS SELECT "+employeeTable+"."+colID+" AS _id,"+
" "+employeeTable+"."+colName+","+
" "+employeeTable+"."+colAge+","+
" "+deptTable+"."+colDeptName+""+
" FROM "+employeeTable+" JOIN "+deptTable+
" ON "+employeeTable+"."+colDept+" ="+deptTable+"."+colDeptID
);
//Inserts pre-defined departments
InsertDepts(db);
}

The method creates tables with columns, a view and a trigger. The method is invoked when the
database is created. So we create our table and specify the columns. This method is invoked
when the database does not exist on the disk, its executed only once on the same device the first
time the application is run on the device.

Upgrading the Database


Sometimes, we want to upgrade the database by changing the schema, add new tables or change
column data types. This is done by overriding the onUpdate(SQLiteDatabase db,int old
Version,int newVerison) method:

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


// TODO Auto-generated method stub

db.execSQL("DROP TABLE IF EXISTS "+employeeTable);


db.execSQL("DROP TABLE IF EXISTS "+deptTable);

db.execSQL("DROP TRIGGER IF EXISTS dept_id_trigger");


db.execSQL("DROP TRIGGER IF EXISTS dept_id_trigger22");
db.execSQL("DROP TRIGGER IF EXISTS fk_empdept_deptid");
db.execSQL("DROP VIEW IF EXISTS "+viewEmps);
onCreate(db);
}

This method is invoked when the version number specified in the constructor of the class
changes.

When you want to append a change to your database, you must change the version number in the
constructor of the class.
So when you pass the constructor a version number of 2:

public DatabaseHelper(Context context) {


super(context, dbName, null,2);

// TODO Auto-generated constructor stub


}

instead of 1:

super(context, dbName, null,2);

the application understands that you want to upgrade the database and onUpgrade method will be
invoked. A typical implementation of this method is to drop the tables and create them again with
the additional modifications.

Managing Foreign-Key Constraints

We mentioned before that SQLite 3 by default does not support foreign key constraint, however
we can force such a constraint using TRIGGERS: we will create a trigger that ensures that when
a new Employee is inserted, his/her Dept value is present in the original Dept table. The SQL
statement to create such a trigger would be like this:

CREATE TRIGGER fk_empdept_deptid Before INSERT ON Employees


FOR EACH ROW BEGIN
SELECT CASE WHEN ((SELECT DeptID FROM Dept WHERE DeptID =new.Dept ) IS
NULL)
THEN RAISE (ABORT,'Foreign Key Violation') END;
END

In onCreate method, we created this trigger like this:

db.execSQL("CREATE TRIGGER fk_empdept_deptid " +


" BEFORE INSERT "+
" ON "+employeeTable+

" FOR EACH ROW BEGIN"+


" SELECT CASE WHEN ((SELECT "+colDeptID+" FROM "+deptTable+" _
WHERE "+colDeptID+"=new."+colDept+" ) IS NULL)"+
" THEN RAISE (ABORT,'Foreign Key Violation') END;"+
" END;");

Executing SQL Statements

Now let's begin executing basic SQL statements. You can execute any SQL statement that is not
a query whether it is insert, delete, update or anything using db.execSQL(String statement)
method like when we did when creating the database tables:

db.execSQL("CREATE TABLE "+deptTable+" ("+colDeptID+ " INTEGER PRIMARY KEY ,


"+ colDeptName+ " TEXT)");

Inserting Records

We insert records to the database using the following code for example to insert records in the
Dept table:

SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(colDeptID, 1);
cv.put(colDeptName, "Sales");
db.insert(deptTable, colDeptID, cv);

cv.put(colDeptID, 2);
cv.put(colDeptName, "IT");
db.insert(deptTable, colDeptID, cv);
db.close();

Notice that we need to call this.getWritableDatabase() to open the connection with the database
for reading/writing. The ContentValues.put has two parameters: Column Name and the value to
be inserted. Also, it is a good practice to close the database after executing statements.

Updating Values

To execute an update statement, we have two ways:

1. To execute db.execSQL
2. To execute db.update method:

public int UpdateEmp(Employee emp)


{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(colName, emp.getName());
cv.put(colAge, emp.getAge());
cv.put(colDept, emp.getDept());
return db.update(employeeTable, cv, colID+"=?",
new String []{String.valueOf(emp.getID())});
}

The update method has the following parameters:

1. String Table: The table to update a value in

2. ContentValues cv: The content values object that has the new values

3. String where clause: The WHERE clause to specify which record to update

4. String[] args: The arguments of the WHERE clause

Deleting Rows

As in update to execute a delete statement, we have two ways:

1. To execute db.execSQL

2. To execute db.delete method:

public void DeleteEmp(Employee emp)


{
SQLiteDatabase db=this.getWritableDatabase();
db.delete(employeeTable,colID+"=?", new String [] {String.valueOf(emp.getID())});
db.close();
}

The delete method has the same parameters as the update method.
Executing Queries

To execute queries, there are two methods:

1. Execute db.rawQuery method

2. Execute db.query method

To execute a raw query to retrieve all departments:

Cursor getAllDepts()
{
SQLiteDatabase db=this.getReadableDatabase();
Cursor cur=db.rawQuery("SELECT "+colDeptID+" as _id,
"+colDeptName+" from "+deptTable,new String [] {});

return cur;
}

The rawQuery method has two parameters:

1. String query: The select statement

2. String[] selection args: The arguments if a WHERE clause is included in the select
statement

Notes

1. The result of a query is returned in Cursor object.

2. In a select statement if the primary key column (the id column) of the table has a name
other than _id, then you have to use an alias in the form SELECT [Column Name] as _id
cause the Cursor object always expects that the primary key column has the name _id or
it will throw an exception .

Another way to perform a query is to use a db.query method. A query to select all employees
in a certain department from a view would be like this:

public Cursor getEmpByDept(String Dept)


{
SQLiteDatabase db=this.getReadableDatabase();
String [] columns=new String[]{"_id",colName,colAge,colDeptName};
Cursor c=db.query(viewEmps, columns, colDeptName+"=?",
new String[]{Dept}, null, null, null);
return c;
}

The db.query has the following parameters:

1. String Table Name: The name of the table to run the query against

2. String [ ] columns: The projection of the query, i.e., the columns to retrieve

3. String WHERE clause: where clause, if none pass null

4. String [ ] selection args: The parameters of the WHERE clause

5. String Group by: A string specifying group by clause

6. String Having: A string specifying HAVING clause

7. String Order By by: A string Order By by clause

Managing Cursors

Result sets of queries are returned in Cursor objects. There are some common methods that you
will use with cursors:

1. boolean moveToNext(): moves the cursor by one record in the result set, returns false if
moved past the last row in the result set.

2. boolean moveToFirst(): moves the cursor to the first row in the result set, returns false if
the result set is empty.

3. boolean moveToPosition(int position): moves the cursor to a certain row index within the
boolean result set, returns false if the position is un-reachable

4. boolean moveToPrevious(): moves the cursor to the previous row in the result set, returns
false if the cursor is past the first row.

5. boolean moveToLast(): moves the cursor to the lase row in the result set, returns false if
the result set is empty.

There are also some useful methods to check the position of a cursor: boolean isAfterLast(),
isBeforeFirst, isFirst, isLast and isNull(columnIndex). Also if you have a result set of only one
row and you need to retrieve values of certain columns, you can do it like this:

public int GetDeptID(String Dept)


{
SQLiteDatabase db=this.getReadableDatabase();
Cursor c=db.query(deptTable, new String[]{colDeptID+" as _id",colDeptName},
colDeptName+"=?", new String[]{Dept}, null, null, null);
//Cursor c=db.rawQuery("SELECT "+colDeptID+" as _id FROM "+deptTable+"
//WHERE "+colDeptName+"=?", new String []{Dept});
c.moveToFirst();
return c.getInt(c.getColumnIndex("_id"));
}

We have Cursor.getColumnIndex(String ColumnName) to get the index of a column. Then to get


the value of a certain column, we have Cursor.getInt(int ColumnIndex) method.

Also there are getShort, getString, getDouble, getBlob to return the value as a byte array. It's a
good practice to close() the cursor after using it.

Data Storage Methods


PreferencesPreferences is a lightweight mechanism to store and retrieve key-value pairs of
primitive data types.

FilesYou can store your data in files on your mobile phone, or in a removable storage
medium.

DatabasesAndroid Api supports SQLite databases. All databases, SQLite and others, are
stored on the device in /data/data/package_name/databases.

NetworkYou can also use the Internet to store and receive data, whether it's an SQLite
database, or just a simple textfile.
Database transactions

In android it is highly important to use transactions when working with databases.

First, in android database operations - especially writing - are very slow. Batching them into
transactions will make them much faster.

Second, the database remains consistent under any circumstances. The database system makes
sure to all the operations in a transaction take effect, or on error, rollback all of them.

If you are used to other platforms like PHP+MySQL where the code usually runs on a powerful
server, witch is not likely to stop execution "unexpectedly", you can be surprised how much it
affects the performance in android.
The android system can kill apps/threads/activities and so interrupt database usage, the battery
can discharge or can be removed etc.

The implementation is very simple, using 3 methods in the SQLiteDatabase class:

beginTransaction();
setTransactionSuccessful();
endTransaction();
Debugging database
Fri, 03/12/2010 - 02:25 | by gabor

SDK Version:

M3

When I first tried to manage an sqlite database on an android device I was not sure about where I
fail in it. Can I even insert the records into the database, or I fail only to read the data from it? So
I started to search for possibilities to debug the database lifecycle.

The system stores databases in the /data/data/package_name/databases folder by default.

In a command line using the adb (Android Debug Bridge - found in the android sdk tools library)
you can access the databases on a running emulator like below:

1. adb -s emulator-5554 shell

2.

3. sqlite3 /data/data/package_name/databases/database_name

After this you can type normal SQL commands to test the content. For example:

1. SELECT * FROM table_name;

This will list the table content (in an ugly format), or say that it does not exists.
Tags:

database

DDMS

debug

SQLite

You might also like