Android,
A Complete Course, From
Basics to Enterprise Edition
Android, A Complete Course, From Basics to Enterprise
Edition
Cet
article est extraie du livre « Android, A Complete Course »,
disponible sur Android2ee.com.
Les
exemples ou les programmes présents dans cet ouvrage sont fournis pour
illustrer les descriptions théoriques. Ce code est libre de toute utilisation
mais n'est pas distribuable.
La
distribution du code est reservée au site :
La
propriété intellectuelle du code appartient à :
L’utilisation
de ces codes est sous votre unique responsabilité et personne d’autre que vous
ne pourra être tenu responsable des préjudices ou dommages de quelques natures
que ce soit pouvant résulter de son utilisation.
Tous
les noms de produits ou marques cités dans cet ouvrage sont des marques déposés
par leurs propriétaires respectifs.
Publié par http://android2ee.com
Titre Original : Android, A Complete Course, From
Basics to Enterprise Edition. Édition Française.
ISBN : 979-10-90388-00-0
Copyright © 2011 by Mathias Séguy
Aucune
représentation ou reproduction, même partielle, autre que celles prévues à
l’article L. 122-5 2° et 3° a) du code de la propriété intellectuelle ne peut
être faite sans l’autorisation expresse de Mathias Seguy ou, le cas échéant,
sans le respect des modalités prévues à l’article L. 122-10 dudit code
La base de données installées sur Android est SQLite, par contre, elle ne se pilote pas avec le JDBC usuel mais avec un SGBDR (Système de Gestion de Base de Données Relationnel) spécifique. Il faut modifier nos vieilles habitudes java d’utilisateurs d’Hibernate, d’Ibatis ou de notre bon vieux JDBC. Une grosse différence concerne le typage des données de vos colonnes qui ne sera pas utilisé par SQLite (il l’est de manière indicative uniquement) : SQLite permet de stocker une valeur de n’importe quel type dans n’importe quelle colonne, quelque soit le type déclaré de cette colonne. D’autres différences ; SQLite ne reconnait pas les contraintes de clefs étrangères, les transactions imbriquées, les jointures externes, certaines variantes d’ALTER TABLE…
Cf. http://www.sqlite.org/docs.html et surtout http://www.sqlite.org/lang.html pour connaître la syntaxe à utiliser.
Comment cela marche-t-il ?
La base de données est liée à votre activité (pour pouvoir partager son accès il faut mettre en place un ContentProvider, cela sera explicité dans un autre chapitre), c’est elle qui la crée, la met à jour, la remplit, l’interroge et la clos. Ainsi dans le onCreate de votre activité vous appelez votre base. Si celle-ci n’existe pas, le code que vous avez implémenté pour la créé est appelé. Si sa structure a évolué le code que vous avez écrit pour la mettre à jour est appelé. Quand vous récupérez votre base, vous la manipulez au travers d’une classe spécifique qui encapsule les appels que vous avez écrit (votre DAO). Quand vous quittez votre activité, dans la méthode Destroy, vous fermez votre base.
Dans la pratique cela implique au moins deux classes spécifiques :
· Votre classe de création et de mise à jour de la base (de la structure de la base) qui étend SQLiteHelper. N’oubliez pas de mettre votre clef primaire technique unique qui s’auto-incrémente pour chacune de vos tables. Enfin, il est préconisé que tous vos noms de tables, de colonnes de la base soient des variables public final static de votre classe. Cette classe implémente au moins trois méthodes :
o Le constructeur qui appelle son super (et qui prend en paramètre le numéro de version de la structure de la base)
o onCreate qui créé la base si elle n’existe pas
o onUpdate qui met à jour votre structure de table si celle-ci à évoluée. Pour savoir si elle a évolué, un numéro de version de la structure de la base est utilisé. En effet elle prend en paramètre un oldVersion et un newVersion.
· Votre classe DAO (vos classes DAO) qui encapsule vos appels à la base. Deux manières d’obtenir votre base de données sont à votre disposition :
o getWritableDatabase() pour l’obtenir en mode écriture (mais du coup évidement c’est un mode lecture/écriture)
o getReadableDatabase() pour l’obtenir en mode lecture seule.
Enfin souvenez-vous que vous devez utiliser les méthodes beginTransaction, endTransaction et commitTransaction si vous faîtes des traitements qui ne sont pas atomiques.
private
SQLiteDatabase db;
@Override
public void open() throws SQLiteException {
try {
db = dbHelper.getWritableDatabase();
} catch (SQLiteException ex) {
db = dbHelper.getReadableDatabase();
}
}
public void close() {
db.close();
}
Où la classe DBHelper est votre classe de création de la base qui étend SQLiteHelper. (cf. ci-dessous pour l’explication).
Commençons par un
exemple:
public class
DBOpenHelper extends SQLiteOpenHelper {
/**@goals This class aims to show the constant to use for the DBOpenHelper*/
public static class
Constants implements BaseColumns {
/**The database name */
public static final
String DATABASE_NAME = "myData.db";
/** The database version */
public static final int DATABASE_VERSION
= 1;
/** The table Name */
public static final
String MY_TABLE = "Human";
// Column name.
/** My Column ID and the associated explanation for end-users */
public static final
String KEY_COL_ID = "_id";// Mandatory
/** My Column Name and the associated explanation for end-users */
public static final
String KEY_COL_NAME = "name";
/** My Column First Name and the associated explanation for end-users */
public static final
String KEY_COL_FIRSTNAME = "firstName";
/** My Column Eyes Color and the associated explanation for end-users */
public static final
String KEY_COL_EYES_COLOR = "eyesColor";
/** My Column Hair color and the associated explanation for end-users */
public static final
String KEY_COL_HAIR_COLOR = "hairColor";
/** My Column age and the associated explanation for end-users */
public static final
String KEY_COL_AGE = "age";
// Indexes des colonnes
/** The index of the column ID */
public static final int ID_COLUMN = 1;
/** The index of the column NAME */
public static final int NAME_COLUMN = 2;
/** The index of the column FIRST NAME */
public static final int FIRSTNAME_COLUMN
= 3;
/** The index of the column EYES COLOR */
public static final int EYES_COLOR_COLUMN
= 4;
/** The index of the column HAIR COLOR */
public static final int HAIR_COLOR_COLUMN
= 5;
/** The index of the column AGE */
public static final int AGE_COLUMN = 6;
}
// The static string to create the database.
private static final
String DATABASE_CREATE =
"create table " + Constants.MY_TABLE + "(" +
Constants.KEY_COL_ID+ "
integer primary key autoincrement, " +
Constants.KEY_COL_AGE + " INTEGER, "
+
Constants.KEY_COL_NAME+ " TEXT, " +
Constants.KEY_COL_FIRSTNAME
+ " TEXT, " +
Constants.KEY_COL_EYES_COLOR
+ " TEXT, "+
Constants.KEY_COL_HAIR_COLOR
+ " TEXT) ";
/**
* @param
context = the context of the caller
* @param
name = Database’s name
* @param
factory = null
* @param
version = Database’s version
*/
public DBOpenHelper(Context
context,
String name,
CursorFactory factory,
int
version)
{
super(context, name, factory, version);
}
/* * (non-Javadoc)
* * @see*
android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)*/
@Override
public void onCreate(SQLiteDatabase
db) {
//Create the new database using the SQL string Database_create
db.execSQL(DATABASE_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) {
Log.w("DBOpenHelper",
"Mise à jour de la version " + oldVersion
+ " vers la version " + newVersion
+
", les anciennes données seront détruites ");
//Drop the old database
db.execSQL("DROP
TABLE IF EXISTS " + Constants.MY_TABLE);
//Create the new one
onCreate(db);
//or do a smartest stuff
}
}
Qui est appelé par votre activité par :
dbOpenHelper = new DBOpenHelper(this, Constants.DATABASE_NAME, null,
Constants.DATABASE_VERSION);
Où:
· Context est le contexte de votre activité (this quand vous êtes dans votre activité)
· Le nom de votre base de données
· Un fabrique de cureur (le plus souvent null)
· Et la version de la structure de votre base.
La syntaxe de création est la suivante :
Ainsi l’exemple précédent créé une table dont le nom est DATABASE_TABLE avec une colonne KEY_ID qui est la clef primaire de type entier qui s’auto-incrémente, une colonne KEY_TASK de type string, non nul, et une colonne KEY_CREATION_DATE de type long.
De plus voilà la syntaxe complète de création d’une table µSQLite :
Collumn-def :
Type-name :
Column-constraint :
Table-constraint :
ForeignKey clauses :
Pour la création et l’instanciation d’une base de données :
/** * The database */
private SQLiteDatabase db;
/** * The database creator and updater
helper */
DBOpenHelper dbOpenHelper;
/** Called when the activity is first
created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Create or
retrieve the database
dbOpenHelper = new DBOpenHelper(this, Constants.DATABASE_NAME, null,
Constants.DATABASE_VERSION);
//open the
database
openDB();
//Insert a new
record
//-------------------
ContentValues
contentValues = new ContentValues();
long rowId = insertRecord(contentValues);
//update that
line
//----------------
rowId = updateRecord(contentValues, rowId);
//Query that
line
//---------------
queryTheDatabase();
//And then
delete it:
//-------------------
deleteRecord(rowId);
}
Pour l’insert :
//
Crée une nouvelle ligne à insérer.
ContentValues
newTaskValues = new
ContentValues();
//Assign the values for each column.
contentValues.put(Constants.KEY_COL_NAME,"name");
contentValues.put(Constants.KEY_COL_FIRSTNAME, "firstName");
contentValues.put(Constants.KEY_COL_EYES_COLOR, "green");
contentValues.put(Constants.KEY_COL_HAIR_COLOR, "blond");
contentValues.put(Constants.KEY_COL_AGE, 6);
// Insert the line in the database
long rowId=db.insert(Constants.MY_TABLE, null, contentValues);
//test to see if the insertion was ok
if(rowId==-1){
Toast.makeText(this, "Error when creating an human", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "Human created and stored in database", Toast.LENGTH_LONG).show();
}
return rowId;
On définit un objet ContentValues dans lequel
on place des paires (NomDeColonne, Valeur) à créer. Puis on utilise notre objet
SQLiteDatabase pour faire l’insert en lui passant, le nom de la table, le nom
d’une colonne (souvent null) et l’objet contenant la carte des paires (colonne,
valeur) à insérer.
Pour l’update:
contentValues.clear();
contentValues.put(Constants.KEY_COL_NAME,"Georges");
contentValues.put(Constants.KEY_COL_FIRSTNAME, "Walter
Bush");
//update the database
rowId=db.update(Constants.MY_TABLE, contentValues, Constants.KEY_COL_ID + "=" + rowId, null);
//test to see if the insertion was ok
if(rowId==-1){
Toast.makeText(this, "Error when updating an human", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "Human updated in database", Toast.LENGTH_LONG).show();
}
return rowId;
On définit l’objet ContentValues dans lequel on place des paires (NomDeColonne, Valeur) à mettre à jour. Puis on utilise notre objet SQLiteDatabase pour faire l’update en lui passant le nom de la table, les valeurs à mettre et la clause where (ici la clef primaire de l’objet).
Pour le delete :
rowId=db.delete(DBOpenHelper.Constants.MY_TABLE,DBOpenHelper.Constants.KEY_COL_ID + "=" + rowId, null);
if(rowId==-1){
Toast.makeText(this, "Error when deleting an human", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "Human deleted in database", Toast.LENGTH_LONG).show();
}
On utilise notre objet SQLiteDatabase pour
faire le delete en lui passant le nom de la table et la clause where (ici la
clef primaire de l’objet).
public long insert (String table, String nullColumnHack, ContentValues values)
Since: API Level 1
Convenience method for inserting a row into the
database.
Parameters
table |
the table to insert the row into |
nullColumnHack |
SQL doesn't allow inserting a completely empty row,
so if initialValues is empty this column will explicitly be assigned a NULL
value |
values |
this map contains the initial column values for the
row. The keys should be the column names and the values the column values |
Returns
the row ID of the newly inserted row, or -1 if an
error occurred
public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
Since: API Level 1
Convenience method for updating rows in the database.
Parameters
table |
the table to update in |
values |
a map from column names to new column values. null
is a valid value that will be translated to NULL. |
whereClause |
the optional WHERE clause to apply when updating.
Passing null will update all rows. |
Returns
the number of rows affected
public int delete (String table, String whereClause, String[] whereArgs)
Since: API Level 1
Convenience method for deleting rows in the database.
Parameters
table |
the table to delete from |
whereClause |
the optional WHERE clause to apply when deleting.
Passing null will delete all rows. |
Returns
the number of rows affected if a whereClause is passed
in, 0 otherwise. To remove all rows and get a count pass "1" as the
whereClause.
Les résultats de requêtes sont renvoyés sous forme d’une liste de pointeurs vers les objets retournés. Cette liste de pointeurs se nomme Cursor. Cette classe possède de nombreuses méthodes :
·
de
mouvements (moveToFirst, moveToLast, moveNext, movePrevious, moveToPosition(int
index)),
·
de
récupérations (getDouble, getFloat, getInt, getLong, getShort, getString,
getBlob),
·
d’informations
(getColunmCount, getColumnName, getColumnIndex, getPosition, getCount…),
·
d’états
(isAfterLast, isBeforeFirst, isClosed, isFirst, isLast, isNull),
· et d’autres méthodes de gestion de l’objet Cursor lui-même.
L’amalgame entre la liste de curseur et la
position du curseur est clair. On bouge dans la liste et en même temps quand on
pointe sur un élément on l’interroge. Il faut s’y faire :
Cursor
cursor
= db.query(Constants.MY_TABLE,projections ,selection, selectionArg, groupBy,having,orderBy, maxResultsListSize);
//then browse the result:
if(cursor.moveToFirst()){
//The elements to retrieve
Integer colId;
String name;
String firstname;
//The associated index within the cursor
int indexId=cursor.getColumnIndex(Constants.KEY_COL_ID);
int indexName=cursor.getColumnIndex(Constants.KEY_COL_NAME);
int indexFirstName=cursor.getColumnIndex(Constants.KEY_COL_FIRSTNAME);
//Browse the results list:
int count=0;
do{
colId=cursor.getInt(indexId);
name=cursor.getString(indexName);
firstname=cursor.getString(indexFirstName);
Toast.makeText(this, "Retrieve element :"+name+","+firstname+" ("+colId+")", Toast.LENGTH_LONG).show();
count++;
}while(cursor.moveToNext());
Toast.makeText(this, "The number of elements retrieved is "+count, Toast.LENGTH_LONG).show();
}else{
Toast.makeText(this, "No element found : ", Toast.LENGTH_LONG).show();
}
Il faut utiliser la méthode query de SQLiteDatabase.
Cette méthode prend en paramètres les éléments suivants :
· Un booléen optionnel spécifiant si le résultat se compose d’éléments uniques (Boolean)
· Le nom de la table à interroger (String)
· Une projection sous forme de tableau de chaines listant les colonnes à inclure dans le résultat (String[])
· Une clause where avec des jokers (?) pour les paramètres si vous le souhaitez (String)
· La liste des paramètres qui remplaceront les jokers (?)(String[])
· Une clause groupBy (String)
· Une clause orderBy dont la syntaxe est nomDeColonne + « ASC||Desc »(String)
· Une limite maximale optionnelle du nombre d’éléments à récupérer (String)
Un exemple :
//Using man made query
//The projection define what are the column you want to retrieve
String[]
projections=new String[] { Constants.KEY_COL_ID,
Constants.KEY_COL_NAME, Constants.KEY_COL_FIRSTNAME };
//And then store the column index answered by the request (we present an
other way to retireve data)
final int cursorIdColNumber=0,cursorNameColNumber=1,cursorFirstNameColNumber=2;
//To add a Where clause:
String
selection=Constants.KEY_COL_HAIR_COLOR+"=?";
String[]
selectionArg=new String[] {"blond"};
//The groupBy clause:
String
groupBy=Constants.KEY_COL_EYES_COLOR;
//The having clause
String
having=null;
// The order by clause (column name followed by Asc or DESC)
String
orderBy
= Constants.KEY_COL_AGE+" ASC";
//Maximal size of the results list
String
maxResultsListSize="60";
Cursor
cursor
= db.query(Constants.MY_TABLE,projections ,selection, selectionArg, groupBy,having,orderBy, maxResultsListSize);
displayResults(cursor);
Vous pouvez utiliser aussi l’objet SQLiteQueryBuilder qui permet d’effectuer des unions et quelques autres opérations de ce type.
Nous reprenons dans l’exemple uniquement une recherche simple :
//Using SQLiteQueryBuilder
//The projection define what are the column you want to retrieve
String[]
projections=new String[] { Constants.KEY_COL_ID,
Constants.KEY_COL_NAME, Constants.KEY_COL_FIRSTNAME };
//And then store the column index answered by the request (we present an
other way to retireve data)
final int cursorIdColNumber=0,cursorNameColNumber=1,cursorFirstNameColNumber=2;
//Adding a where clause:
String
selection=Constants.KEY_COL_HAIR_COLOR+"=?";
String[]
selectionArg=new String[] {"blond"};
//The groupBy clause:
String
groupBy=Constants.KEY_COL_EYES_COLOR;
//The having clause
String
having=null;
// The order by clause (column name followed by Asc or DESC)
String
orderBy
= Constants.KEY_COL_AGE+" ASC";
//Using the QueryBuilder
//Create a Query SQLite object
SQLiteQueryBuilder
qb = new
SQLiteQueryBuilder();
qb.setTables(Constants.MY_TABLE);
//qb.appendWhere(Constants.KEY_COL_HAIR_COLOR+ "=blond");
qb.setDistinct(true);
cursor=qb.query(db,projections ,selection, selectionArg, groupBy,having,orderBy);
displayResults(cursor);
Les transactions peuvent avoir un listener, ce qui est une bonne pratique mais vous pouvez vous en passer (ce qui est une mauvaise pratique).
Le pattern
standard d’utilisation des transactions est:
Soit db.beginTransactionWithListener(listener);
Soit db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
Le listener est du type:
public void beginTransactionWithListener
(SQLiteTransactionListener
transactionListener)
Cet exemple montre comment mettre en place une base de données et communiquer avec elle à partir d’une activité. Il y a deux classes, la classe d’instanciation de la base et la classe d’utilisation de cette base.
La classe de
création :
public class
DBOpenHelper extends SQLiteOpenHelper {
/** @goals This class aims to show the constant to use for the DBOpenHelper */
public static class
Constants implements BaseColumns {
/** The database name */
public static final
String DATABASE_NAME = "myData.db";
/** The database version */
public static final int DATABASE_VERSION
= 1;
/** The table Name */
public static final
String MY_TABLE = "Human";
//
Noms de colonnes
//
/!\Si vous utilisez une base de données, les noms des colonnes ont les mêmes
que ceux de
//
votre bases, de même pour les indexes.
/** My Column ID and the associated explanation for
end-users
*/
public static final
String KEY_COL_ID = "_id";// Mandatory
/** My Column Name and the associated explanation for
end-users
*/
public static final
String KEY_COL_NAME = "name";
/** My Column First Name and the associated
explanation for end-users
*/
public static final
String KEY_COL_FIRSTNAME = "firstName";
/** My Column Eyes Color and the associated
explanation for end-users
*/
public static final
String KEY_COL_EYES_COLOR = "eyesColor";
/** My Column Hair color and the associated
explanation for end-users
*/
public static final
String KEY_COL_HAIR_COLOR = "hairColor";
/** My Column age and the associated explanation for
end-users
*/
public static final
String KEY_COL_AGE = "age";
// Indexes des colonnes
/** The index of the column ID */
public static final int ID_COLUMN = 1;
/** The index of the column NAME */
public static final int NAME_COLUMN = 2;
/** The index of the column FIRST NAME */
public static final int FIRSTNAME_COLUMN
= 3;
/** The index of the column EYES COLOR */
public static final int EYES_COLOR_COLUMN
= 4;
/** The index of the column HAIR COLOR */
public static final int HAIR_COLOR_COLUMN
= 5;
/** The index of the column AGE */
public static final int AGE_COLUMN = 6;
}
// The static string to create the database.
private static final String DATABASE_CREATE =
"create table " + Constants.MY_TABLE + "(" +
Constants.KEY_COL_ID+ "
integer primary key autoincrement, " +
Constants.KEY_COL_AGE + " INTEGER, "
+
Constants.KEY_COL_NAME+ " TEXT, " +
Constants.KEY_COL_FIRSTNAME
+ " TEXT, " +
Constants.KEY_COL_EYES_COLOR
+ " TEXT, "+
Constants.KEY_COL_HAIR_COLOR
+ " TEXT) ";
/**
* @param context
* @param name
* @param factory
* @param version
*/
public DBOpenHelper(Context
context,
String name,
CursorFactory factory,
int
version)
{
super(context, name, factory, version);
}
/*
* * (non-Javadoc) * @see*
*
android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
*/
@Override
public void onCreate(SQLiteDatabase
db) {
// Create the new database using the SQL string
Database_create
db.execSQL(DATABASE_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) {
Log.w("DBOpenHelper",
"Mise à jour de la version " + oldVersion
+ " vers la version " + newVersion
+
", les anciennes données seront détruites ");
// Drop the old database
db.execSQL("DROP TABLE IF EXISTS " + Constants.MY_TABLE);
// Create the new one
onCreate(db);
// or do a smartest stuff
}
}
La classe
d’utilisation :
public class
DataBaseTuto extends Activity {
/** * The database */
private
SQLiteDatabase db;
/** * The database creator and updater helper */
DBOpenHelper dbOpenHelper;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle
savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create or retrieve the database
dbOpenHelper = new DBOpenHelper(this, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION);
// open the database
openDB();
// Insert a new record
// -------------------
ContentValues contentValues = new
ContentValues();
long rowId = insertRecord(contentValues);
// update that line
// ----------------
rowId = updateRecord(contentValues, rowId);
// Query that line
// ---------------
queryTheDatabase();
// And then delete it:
// -------------------
deleteRecord(rowId);
}
/*********************************************************************************/
/** Managing LifeCycle and database open/close operations
*********************************/
/*********************************************************************************/
/* * (non-Javadoc)** @see
android.app.Activity#onResume() */
@Override
protected void onResume()
{
super.onResume();
openDB();
}
/* * (non-Javadoc)** @see
android.app.Activity#onPause() */
@Override
protected void onPause()
{
super.onPause();
closeDB();
}
/** * Open the database* *
* @throws SQLiteException
*/
public void openDB()
throws
SQLiteException {
try {
db = dbOpenHelper.getWritableDatabase();
} catch
(SQLiteException ex) {
db = dbOpenHelper.getReadableDatabase();
}
}
/** *Close Database */
public void closeDB()
{
db.close();
}
/****************************************************************************************/
/** Managing Records **********************************************************************/
/****************************************************************************************/
/**
* Insert a record
*
* @param contentValues
*
(an empty contentValues)
* @return the inserted row id
*/
private long insertRecord(ContentValues
contentValues) {
// Assign the values for each column.
contentValues.put(Constants.KEY_COL_NAME, "name");
contentValues.put(Constants.KEY_COL_FIRSTNAME,
"firstName");
contentValues.put(Constants.KEY_COL_EYES_COLOR,
"green");
contentValues.put(Constants.KEY_COL_HAIR_COLOR,
"blond");
contentValues.put(Constants.KEY_COL_AGE, 6);
// Insert the line in the database
long rowId = db.insert(Constants.MY_TABLE, null, contentValues);
// test to see if the insertion was ok
if (rowId == -1) {
Toast.makeText(this, "Error when creating an human",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Human created and stored in database",
Toast.LENGTH_LONG).show();
}
return rowId;
}
/**
* * Update a record
*
* @param contentValues
* @param rowId
* @return the updated row id
*/
private long updateRecord(ContentValues
contentValues, long rowId) {
contentValues.clear();
contentValues.put(Constants.KEY_COL_NAME, "Georges");
contentValues.put(Constants.KEY_COL_FIRSTNAME,
"Walter Bush");
// update the database
rowId = db.update(Constants.MY_TABLE, contentValues,
Constants.KEY_COL_ID + "=" + rowId, null);
// test to see if the insertion was ok
if (rowId == -1) {
Toast.makeText(this, "Error when updating an human",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Human updated in database", Toast.LENGTH_LONG).show();
}
return rowId;
}
/** * Delete a Record *
* @param rowId
*/
private void deleteRecord(long rowId) {
rowId = db.delete(DBOpenHelper.Constants.MY_TABLE,
DBOpenHelper.Constants.KEY_COL_ID + "=" + rowId, null);
if (rowId == -1) {
Toast.makeText(this, "Error when deleting an human",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Human deleted in database", Toast.LENGTH_LONG).show();
}
}
/** *Query a the database */
private void queryTheDatabase()
{
// Using man made query
// The projection define what are the column you want
to retrieve
String[] projections = new
String[] { Constants.KEY_COL_ID, Constants.KEY_COL_NAME,
Constants.KEY_COL_FIRSTNAME
};
// And then store the column index answered by the
request (we present an other way to
// retireve data)
final int cursorIdColNumber
= 0,
cursorNameColNumber = 1,
cursorFirstNameColNumber = 2;
// To add a Where clause you can either do that:
// qb.appendWhere(Constants.KEY_COL_HAIR_COLOR+
"=blond");
// Or that:
String selection =
Constants.KEY_COL_HAIR_COLOR + "=?";
String[] selectionArg = new
String[] { "blond" };
// The groupBy clause:
String groupBy =
Constants.KEY_COL_EYES_COLOR;
// The having clause
String having = null;
// The order by clause (column name followed by Asc or
DESC)
String orderBy =
Constants.KEY_COL_AGE + " ASC";
// Maximal size of the results list
String maxResultsListSize = "60";
Cursor cursor = db.query(Constants.MY_TABLE, projections, selection, selectionArg,
groupBy,
having, orderBy,maxResultsListSize);
displayResults(cursor);
// Using the QueryBuilder
// Create a Query SQLite object
SQLiteQueryBuilder
qb = new
SQLiteQueryBuilder();
qb.setTables(Constants.MY_TABLE);
// qb.appendWhere(Constants.KEY_COL_HAIR_COLOR+
"=blond");
qb.setDistinct(true);
cursor = qb.query(db, projections, selection, selectionArg, groupBy, having, orderBy);
displayResults(cursor);
}
/**
* Display the results stored in the cursor
*
* @param cursor
*/
private void displayResults(Cursor
cursor)
{
// then browse the result:
if (cursor.moveToFirst()) {
// The elements to retrieve
Integer
colId;
String
name;
String
firstname;
// The associated index within the cursor
int indexId = cursor.getColumnIndex(Constants.KEY_COL_ID);
int indexName = cursor.getColumnIndex(Constants.KEY_COL_NAME);
int indexFirstName = cursor.getColumnIndex(Constants.KEY_COL_FIRSTNAME);
// Browse the results list:
int count = 0;
do {
colId = cursor.getInt(indexId);
name = cursor.getString(indexName);
firstname = cursor.getString(indexFirstName);
Toast.makeText(this, "Retrieve element :" + name + "," + firstname +
" (" + colId + ")",Toast.LENGTH_LONG).show();
count++;
}
while
(cursor.moveToNext());
Toast.makeText(this, "The number of elements retrieved is " + count,
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "No element found : ", Toast.LENGTH_LONG).show();
}
}
}