Professional Documents
Culture Documents
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.
Shared Preferences
Internal Storage
External Storage
SQLite Databases
Network Connection
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 supports standard relational database features like SQL syntax, transactions and
prepared statements. In addition
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.
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
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.
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
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.
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.
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.
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.
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.
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:
Now insert a single row with the text 'en_US' in the "android_metadata" table:
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".
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.
/**
* 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) {
/**
* Creates a empty database on the system and rewrites it with your own
database.
* */
public void createDataBase() throws IOException{
if(dbExist){
//do nothing - database already exist
}else{
try {
copyDataBase();
} catch (IOException e) {
}
}
/**
* 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(){
try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}catch(SQLiteException e){
if(checkDB != null){
checkDB.close();
/**
* 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{
}
public void openDataBase() throws SQLException{
@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.
...
try {
myDbHelper.createDataBase();
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
...
http://www.codeproject.com/KB/android/AndroidSQLite.aspx
Introduction
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.
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
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:
The Constructor
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.
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:
instead of 1:
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.
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:
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:
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
1. To execute db.execSQL
2. To execute db.update method:
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
Deleting Rows
1. To execute db.execSQL
The delete method has the same parameters as the update method.
Executing Queries
Cursor getAllDepts()
{
SQLiteDatabase db=this.getReadableDatabase();
Cursor cur=db.rawQuery("SELECT "+colDeptID+" as _id,
"+colDeptName+" from "+deptTable,new String [] {});
return cur;
}
2. String[] selection args: The arguments if a WHERE clause is included in the select
statement
Notes
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:
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
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:
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.
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
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.
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.
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:
2.
3. sqlite3 /data/data/package_name/databases/database_name
After this you can type normal SQL commands to test the content. For example:
This will list the table content (in an ugly format), or say that it does not exists.
Tags:
database
DDMS
debug
SQLite