Android/Arquitectura BD SQlite
Introducció a SQLite
modificaSQLite és un gestor de bases de dades de codi obert que permet gestionar bases de dades relacionals de forma simple amb un cost de memòria molt reduït, cosa que el converteix en un candidat ideal per estar integrat en altres sistemes i/o aplicacions.
En les bases de dades relacionals, les dades estan organitzades per taules. Una taula és un conjunt de valors organitzats utilitzant un model de columnes verticals i files horitzontals. Una columna és un conjunt de valors del mateix tipus (identificats pels seus noms), un per cada fila de la taula. Un camp es un valor que existeix en una intersecció entre una fila i una columna. Una clau primària identifica de forma única cadascuna de les files de la taula mentre que la clau forana és una referència entre dues taules.
SQLite està integrat en tots els dispositius Android i també en aplicacions i navegadors d'Internet (Chrome, Firefox). La utilizació d'una base de dades en Android no precisa d'una instal·lació o administració de la mateixa; només s'han de definir les declaracions en SQL per crear/actualitzar les dades de la base de dades.
Els accessos a una base de dades SQLite precisen de l'accés al sistema de fitxers. Per tant, es recomanable realitzar operacions a la base de dades de forma asíncrona.
El contingut d'aquest article mostra un exemple de creació d'una petita base de dades seguint l'standard que proposa Google. La principal diferència entre l'standard i una aplicació feta ràpidament és que l'standard defineix una estructura de classes determinada. L'standard proposa 3 classes:
- Una classe Contracte (per exemple, DBContract), que s'encarrega de definir les constants de la base de dades.
- Una classe Helper (que estén de DBHelper), que s'encarrega d'obrir/crear/actualitzar la base de dades.
- Una classe Manager (per exemple, DBManager), que s'encarrega de gestionar la base de dades.
Aquesta estructura no és obligatòria per gestionar una base de dades (es poden tenir totes les classes implementades en una de sola); però és recomanable utilitzar-la a mode de facilitar l'estructuració, el manteniment i la llegibilitat d'aquesta.
SQLite en l'entorn Android
modificaA diferència d'altres àmbits de les bases de dades, en el desenvolupament d'aplicacions mòbils SQLite és un dels 5 gestors de bases de dades més utilitzats. Partim d'un gestor de base de dades que treballa amb tipus de dades més petites respecte altres gestors i per tant que ens permet reduir les dimensions de la nostra aplicació. Un altre punt a favor és que es pot utilitzar directament sense cap tipus de configuració, sense haver de configurar paràmetres d'un servidor. Aquesta combinació de característiques proporciona accessos ràpids a memòria i una fàcil usabilitat a nivell de codi.
Les dades que guarda SQLite són emmagatzemades dins d'un dispositiu mòbil com a text, per tant, no és necessari haver d'utilitzar un administrador de bases de dades. Això ens permet que la informació desada d'una aplicació pugui ser utilitzada en multiplataforma. També està suportat l'ús de SQLite en IOS, Blackberry i Windows Phone.
Database Contract
modificaUn dels principals principis de les bases de dades SQL són els esquemes (schema). L'esquema és una declaració formal sobre com una base de dades s'organitza, que queda reflectit en les sentències SQL utilitzades per crear la base de dades. És recomanable crear una classe (Contract) que específica explícitament l'esquema de la base de dades.
La classe Contract és un contenidor de constants que defineix noms per les taules, les columnes i les URIs (Uniform Resource Identifier). Amb l'ús de la classe Contract independitzem els noms de les taules i els atributs del a base de dades, de l'ús d'aquesta.
El contingut necessari que ha de tenir la classe contract és:[1]
- DATABASE_VERSION : integer que defineix la versió de la base de dades. Aquest valor s'usa, com expliquem més endavant, per tal de detectar si la definició de la base de dades ha canviat i per tant s'ha de prendre alguna decisió al respecte.
- DATABASE_NAME : String que defineix el nom de la base de dades.
Dins de la classe Contract`` cada taula de la base de dades s'ha de definir com una nova classe que implementi la classe BaseColumns[2].
Per cada taula s'ha de definir:
- TABLE_NAME : String que defineix quin és el nom de la taula.
- COLUMN_NAME : String que defineix quin és el nom d'una columna de la base de dades. S'han de definir tantes com columnes tingui la taula.
- CREATE_TABLE : String que defineix la instrucció encarregada de realitzar la creació de la taula. El contingut d'aquesta constant està formulada en el llenguatge SQL.
- DROP_TABLE : String que defineix la instrucció encarregada de destruir la taula. El contingut d'aquesta constant està formulada en el llenguatge SQL.
Exemple
modificaEn el següent codi es mostra un exemple que té definides tres taules: la taula Table1 que defineix els usuaris; aquests usuaris disposen del seu name i email, cada un d'aquests atributs corresponent a una columna. La taula Table2 defineix les xarxes socials, amb els atributs name i counter que determinen, respectivament, el nom i quantes subscripcions (usuaris) disposa aquella xarxa social i l'última taula, Table12 indica la relació entre les dues taules anteriors on per cada parell de dades email i nom té una register_date que indica la data de registre d'aquest usuari a la determinada xarxa social.
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
import android.provider.BaseColumns;
/**
* Classe Contract. Defineix constants per la base de dades.
*/
public final class DBContract {
// Inicialització de les variables comunes que s'utilitzaran per la creació de les taules
public static final int DATABASE_VERSION = 1; // Versió de la bd
public static final String DATABASE_NAME = "dbexample.db"; // Nom de la bd
private static final String TEXT_TYPE = " TEXT"; // Tipus de text
private static final String INTEGER_TYPE = " INTEGER"; // Tipus d'enter
private static final String COMMA_SEP = ","; // Separació
/**
* Constructora. Se sol definir així per tal que la crida de la constructora de la classe
* Contract no tingui cap efecte.
*/
private DBContract() {}
/**
* Classe Table1 (usuaris).
*/
public static abstract class Table1 implements BaseColumns {
public static final String TABLE_NAME = "user";
public static final String COLUMN_NAME_COL1 = "name";
public static final String COLUMN_NAME_COL2 = "email";
// String que proporciona la creació de la taula "Table1"
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP +
COLUMN_NAME_COL2 + TEXT_TYPE + " UNIQUE )";
// String que proporciona l'eliminació de la taula "Table1"
public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
}
/**
* Classe Table2 (xarxes socials).
*/
public static abstract class Table2 implements BaseColumns {
public static final String TABLE_NAME = "social";
public static final String COLUMN_NAME_COL1 = "name";
public static final String COLUMN_NAME_COL2 = "counter";
// String que proporciona la creació de la taula "Table2"
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_NAME_COL1 + TEXT_TYPE + " UNIQUE" + COMMA_SEP +
COLUMN_NAME_COL2 + INTEGER_TYPE + " )";
// String que proporciona l'eliminació de la taula "Table2"
public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
}
/**
* Classe Table12 (interrelació n a m entre usuaris i xarxes socials).
*/
public static abstract class Table12 implements BaseColumns {
public static final String TABLE_NAME = "relation";
public static final String COLUMN_NAME_COL1 = "email";
public static final String COLUMN_NAME_COL2 = "name";
public static final String COLUMN_NAME_COL3 = "register_date";
// String que proporciona la creació de la taula "Table12"
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP +
COLUMN_NAME_COL2 + TEXT_TYPE + COMMA_SEP +
COLUMN_NAME_COL3 + TEXT_TYPE + " )";
// String que proporciona l'eliminació de la taula "Table12"
public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
}
}
Database Helper
modificaLa classe Database Helper (DBHelper) es una classe que s'ha d'estendre de la classe abstract SQLiteOpenHelper. Aquesta classe s'encarrega de proporcionar l'accés a la base de dades i d'actualitzar-la si aquesta ja existís o crear-la de nou si no existís o el sistema ho requerís.
S'ha de fer l'override dels 2 mètodes de la classe la qual s'està estenent:
- onCreate : mètode que ha de contenir les instruccions necessàries per crear la base de dades. Sobre l'objecte SQLiteDatabase que es rep per paràmetre usarem la funció execSQL per executar les sentències sQL necessàries. Cada crida a execSQL crearà una taula o un índex: per tant l'argument de cada crida a la funció execSQL és una de les constants de creació definides unes constants en la classe Contract.
- onUpgrade : mètode que ha de contenir les instruccions necessàries per tal d'actualitzar la base de dades quan hi ha un canvi d'esquema. Aquest mètode s'executa quan el número de la versió de la base de dades (definit en la classe Contract) és superior respecte la versió de la base de dades instal·lada. En el cos del mètode se sol prendre la decisió respecte el canvi de versió. Per exemple, si se sap que per canviar d'una versió 'i' a una versió 'j' l'únic que s'ha fet es crear una taula nova, es pot executar només aquesta instrucció. O també, per exemple, es pot es pot fer el buidatge de la base de dades sencera i tornar-la a crear de nou. Les instruccions tornen a ser funcions execSQL de l'objecte tipus SQLiteDatabase que es rep per paràmentre, passant-li com a argument les accions definides en la classe Contract.
També s'ha d'escriure el constructor de la classe, que s'encarregarà de enviar a la seva classe super (SQLiteOpenHelper en aquest cas) el context d'execució, el nom de la base de dades (definit al Contract), el cursor (si es vol definir, sinó s'indica com a null) i la versió de la base de dades. El Context és una classe abstracta, la implementació de la qual està proporcionada per el sistema Android; el context permet els accessos als recursos específics de l'aplicació, com les bases de dades pròpies.
Exemple
modificaA continuació es continua mostrant l'exemple anterior, en aquest cas la classe Helper.
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Classe DBHelper.
*/
public class DBHelper extends SQLiteOpenHelper{
/**
* Constructora.
* @param context: Context de l'aplicació.
*/
public DBHelper(Context context) {
/* Cridem a la classe super (SQLiteOpenHelper) passant-li el context, el nom de
la base de dades i la versió d'aquesta */
super(context, DBContract.DATABASE_NAME, null, DBContract.DATABASE_VERSION);
}
/**
* onCreate. Crea la base de dades en cas de que no existeixi.
* @param db: La nostra base de dades.
*/
@Override
public void onCreate(SQLiteDatabase db) {
/* Execució de sentències SQL que s'encarreguen de cridar a la classe Contract on,
amb l'String CREATE_TABLE, es pot procedir a la creació de les taules */
db.execSQL(DBContract.Table1.CREATE_TABLE);
db.execSQL(DBContract.Table2.CREATE_TABLE);
db.execSQL(DBContract.Table12.CREATE_TABLE);
}
/**
* Mètode onUpgrade. Actualitza la base de dades eliminant-la i tornant-la a construir.
* @param db: La nostra base de dades.
* @param oldVersion: Número de la versió antiga de la bd.
* @param newVersion: Número de la nova versió de la bd.
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/* Com passa amb el mètode onCreate cridem, a la classe Contract, per a
l'eliminació de cadascuna de les taules (DELETE_TABLE és l'String que procedeix a
l'eliminació */
db.execSQL(DBContract.Table1.DELETE_TABLE);
db.execSQL(DBContract.Table2.DELETE_TABLE);
db.execSQL(DBContract.Table12.DELETE_TABLE);
/* Una vegada eliminada la bd, cridem a onCreate per tornar-la a construir */
onCreate(db);
}
}
Database Manager
modificaOperacions sobre la base de dades
modificaLa classe Manager no es cap recomanació de l'standard de Google. Però s'introdueix per simetria amb les recomanacions de Google: és una classe que agrupa totes les interaccions que es duen amb la base de dades. Així les diferents interaccions amb la base de dades queden totes concentrades en una sola classe, i no pas disperses pel codi.
Principalment existeixen quatre tipus d'interaccions amb una base de dades:
- insert : acció de introduir noves files a una taula de la base de dades.
- update : acció d'actualitzar una fila de la base de dades introduïda anteriorment.
- delete : acció d'eliminar d'una taula d'una base de dades una fila de la que ja no es vulgui conservar la seva informació.
- query : acció d'obtenir algun tipus d'informació de la base de dades.
Exemple
modificaEn tot moment la classe Manager ha de tenir visibiltiat sobre la classe helper, que és qui ens proporciona l'accés a la base de dades. Per això en l'exemple fem que el constructor de Manager sigui l'encarregat de crear l'objecte de la classe Helper i de mantenir-lo com un membre de dades de la classe. A continuació es mostra el codi d'aquest constructor.
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
import android.content.Context;
/**
* Classe DBManager. Facilita la gestió de les consultes.
*/
public class DBManager {
private DBHelper dbHelper;
/**
* Constructora.
* @param context: Context de l'apliació.
*/
DBManager(Context context) {
this.dbHelper = new DBHelper(context);
}
}
Permisos d'accés
modificaCal destacar que totes les interaccions necessiten accedir a la base de dades, i per això prèviament se n'ha de demanar el permís d'accés. Aquest permís pot ser:
- Permís de lectura : S'atorga si la classe helper de la base de dades no ha atorgat el permís d'escriptura a ningú. Dos permisos de lectura són permesos simultàniament.
public SQLiteDatabase SQLiteOpenHelper::getReadableDatabase();
- Permís d'escriptura: Aquest permís s'atorga si la classe Helper de la base de dades no ha atorgat cap permís ja sigui d'escriptura o de lectura.
public SQLiteDatabase SQLiteOpenHelper::getWritableDatabase();
Per indicar que el permís d'accés a la base de dades ja no és necessari, i per tant es pot suprimir, s'ha d'executar la següent comanda:
public synchronized void SQLiteOpenHelper::close();
Exemple
modificaTot seguit es mostren un o més exemples de cada interacció amb la base de dades, xcorresponents a l'exemple ja definit a l'inici de l'article.
Interacció Insert
modificaLa interacció d'inserir files en la base de dades requereix el permís d'accés del tipus escriptura a la base de dades.
La manera més simple d'inserir una nova fila és mitjançant un objecte ContentValues.
La funció necessària per a fer l'insert es la següent:
public long SQLiteDatabase::insert(String table, String nullColumnHack, ContentValues values);
Els seus paràmetres indiquen:
- table : String que indica la taula on s'inserirà la fila.
- nullColumnHack :
- values : contentValues que conté el contingut de la fila.
Aquesta funció retorna -1 si s'ha produït algun error durant la inserció. Un exemple d'error en la inserció és l'intent d'afegir una fila que ja està a la taula. Si no hi ha cap error, retorna l'índex de la fila que s'acaba de crear.
Un exemple d'inserir és el codi següent en el qual s'insereix una nova fila a la taula 1 amb el parell name i email:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
public void insereix(String name, String email) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(DBContract.Table1.COLUMN_NAME_COL1, name);
values.put(DBContract.Table1.COLUMN_NAME_COL2, email);
db.insert(DBContract.Table1.TABLE_NAME, null, values);
}
Interacció Update
modificaLa interacció de sobrescriure files en la base de dades requereix el permís d'accés del tipus escriptura a la base de dades.
Igual que en la inserció d'una nova fila, la manera més simple de modificar una fila existent és mitjançant un objecte ContentValues.
La funció necessària per sobrescriure una fila és la següent:
public int SQLiteDatabase::update(String table, ContentValues values, String whereClause, String[] whereArgs);
Els seus paràmetres indiquen:
- table : String que indica la taula on es sobreescriurà la fila.
- values : contentValues que conté el contingut a modificar.
- whereClause : String que indica la columna que es compararà amb el contingut del següent argument sempre que la columna es concateni amb l'String "=?". Si aquest argument és null significa que efectuarà la sobreescriure en totes les columnes.
- whereArgs : string[] que indica tots els valors els quals pot prendre la columna indicada en el argument anterior.
Aquesta funció retorna el número de files afectades.
Un exemple de sobreescriure és el codi següent en què es sobreescriu la columna que indica el comptador d'usuaris de la xarxa social de la taula 2:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
private void incrementa(String social, int counter) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
values = new ContentValues();
values.put(DBContract.Table2.COLUMN_NAME_COL2, counter);
db.update(DBContract.Table2.TABLE_NAME, values, DBContract.Table2.COLUMN_NAME_COL1 + "=?", new String[] {social});
}
Interacció Delete
modificaLa interacció d'eliminar files de la base de dades requereix el permís d'accés del tipus escriptura a la base de dades.
La funció necessària per eliminar una fila és la següent:
public int SQLiteDatabase::delete(String table, String whereClause, String[] whereArgs);
Els seus paràmetres indiquen:
- table : String que indica la taula d'on s'esborrarà la fila.
- whereClause : String que indica la columna que es compararà amb el contingut del següent argument sempre que la columna es concateni amb l'string "=?". Si aquest argument és null significa que s'eliminaran totes les columnes.
- whereArgs : string[] que indica tots els valors que pot prendre la columna indicada en l'argument anterior.
Aquesta funció retorna el número de files afectades si s'indica ´whereClause, altrament retorna 0. Si es volen eliminar totes les files i saber quantes s'han eliminat s'ha d'indicar "1" en el paràmetre whereClause.
Un exemple d'eliminar és el codi següent en el qual s'elimina la fila de la taula 2 de la xarxa social que s'indica per paràmetre:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
private void eliminar(String social) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete(DBContract.Table2.TABLE_NAME, DBContract.Table2.COLUMN_NAME_COL1 + "=?", new String[] {social});
db.close();
}
Interacció Query
modificaLa interacció d'obtenir informació d'una taula de la base de dades requereix el permís d'accés del tipus lectura a la base de dades.
Les funcions que ens permeten fer les consultes sempre ens retornen un objecte. Cursor
La funció necessària per realitzar aquesta consulta té principalment quatre variants:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
public Cursor SQLiteDatabase::query(String table, String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy);
public Cursor SQLiteDatabase::query(String table, String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy, String limit);
public Cursor SQLiteDatabase::query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy, String limit);
public Cursor SQLiteDatabase::query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs,
String groupBy, String having, String orderBy, String limit, CancellationSignal cancellationSignal);
Els seus paràmetres indiquen:
- distinct : booleà que indica si es volen suprimir les files repetides.
- table : String que indica la taula on se sobrescriurà la fila.
- columns : String[] que indica el llistat de columnes que es mostraran. Si aquest argument és null s'ignifica que es mostraran totes les columnes.
- selection : String que indica la columna que es compararà amb el contingut del següent argument sempre que la columna es concateni amb l'string "=?". Si aquest argument és null significa es retornaran totes les columnes.
- selectionArgs : String[] el qual indica tots els valors que pot prendre la columna indicada en l'argument anterior.
- groupBy : String que indica com s'aplica el filtre de group by de l'SQL. Si aquest argument és null llavors no s'aplicarà cap filtre.
- having : String que indica quins grups creats pel filtre group byes visualitzen. Si l'argument és null llavors es visualitzen tots els grups. Si l'argument groupBy és null és obligatori que aquest també ho sigui.
- orderBy : String que indica amb quin ordre visualitzen les files. Si aquest argument és null llavors és mostraran amb l'ordre per defecte.
- limit : String que indica quin es el límit de files mostrades. Si aquest argument és null es mostraran totes les files possibles.
- cancellationSignal : cancellationSignal que permet indicar qui enviarà un signal de cancelació si es vol interrompre la query. L'enviament del signal provoca l'exepció OperationCanceledException.
Aquesta funció retorna el número de files afectades si s'indica whereClause, altrament retorna 0.
Un exemple de consulta és el codi següent en el qual pretén saber a quines xarxes socials està subscrit l'usuari indicat per paràmetre:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
private List<String> consulta(String usuari) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
List<String> list = new ArrayList<String>();
Cursor cursor = db.query(DBContract.Table12.TABLE_NAME, new String[] {DBContract.Table12.COLUMN_NAME_COL2}, DBContract.Table12.COLUMN_NAME_COL2 + "=?", new String[] {usuari}, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
String value = cursor.getString(cursor.getColumnIndex(DBContract.Table12.COLUMN_NAME_COL2));
list.add(value);
} while (cursor.moveToNext());
}
}
return list;
}
Hi ha un altre tipus de consulta, no gaire recomanable, que permet realitzar qualsevol query en format SQL. La funció és la següent:
public Cursor SQLiteDatabase::rawQuery(String sql, String[] selectionArgs)
Els seus paràmetres indiquen:
- sql : String que indica la consulta SQL; aquesta no ha d'acabar amb ;.
- selectionArgs : String[] que indica tots els valors els quals compara la clàusula selection si aquesta acaba amb l'String "=?".
Classe ContentProvider
modificaUna base de dades en sistemes Android és privada per l'aplicació que la crea; no existeix un espai comú d'emmagatzemament en el que diferents aplicacions la puguin compartir. Per tal que diferents aplicacions puguin utilitzar una mateixa base de dades, el sistema Android proveeix els ContentProvider.
El ContentProvider és un dels components primaris de les aplicacions d'Android; proporcionen contingut a les aplicacions. S'encarreguen d'encapsular les dades i de proporcionar-les a les aplicacions a través d'una sola interficie ContentResolver. El ContentProvider és necessari quan s'hagin de compartir dades entre múltiples aplicacions. Si no s'han de compartir les dades entre moltes aplicacions es pot utilitzar una base de dades a través de la classe SQLiteDatabase.
Quan una petició es fa a través d'un ContentResolver el sistema inspecciona l'autoritat de la URI donada i es passa la petició al ContentProvider registrat en l'autoritat.
Classe ContentResolver
modificaLa classe ContentResolver s'encarrega d'obtenir/extraure les dades proporcionades per el ContentProvider. Aquestes dades es comuniquen amb el ContentProvider, determinades per la URI donada. Així que, quan volem obtenir les dades del ContentResolver, el sistema avalua la URI donada i envia la petició al ContentProvider.
Per obtenir l'objecte de tipus ContentResolver s'utilitza el mètode getContentResolver().
Classe ContentValues
modificaLa classe ContentValues es necessita per tal d'introduir una fila a una taula de la base de dades. A continuació es mostra un exemple del procediment a seguir:
ContentValues values = new ContentValues();
values.put(key, value);
Aquest objecte permet crear una fila indicant el parell clau i valor de totes les columnes de la taula. Per tal de definir el paràmetre key s'usa la constant necessària de la classe Contract.
Classe Cursor
modificaLa classe Cursor es necessita per tal d'obtenir el resultat d'una query. Normalment se sol iterar el cursor i se n'obtenen els valors que a retornat la query.
Un exemple d'aquest recorregut:
- Link al repositori: Pàgina principal d'Android
- Anotacions: No
- Vegeu també: No
public List<String> recorregut(Cursor cursor) {
List<String> contingut = new ArrayList<String>();
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
/*COLUMNA indica la contant la qual defineix la columna que es vol obtenir*/
String value = cursor.getString(cursor.getColumnIndex(COLUMNA));
contingut.add(value);
}while (cursor.moveToNext());
}
cursor.close();
}
return contingut;
}
Notes
modifica- ↑ El que importa és definir les constants amb la semàntica indicada. El nom emprat és decisió del programador.
- ↑ La classe BaseColumns s'encarrega d'afegir a la nostra definició de base de dades el tag _ID com a nom de l'atribut identificador de cada fila; i _COUNT, que indica quantes files té la taula. Aquests tags els agefeix BaseColumns per tal que les classes DBHelper i DBManager puguin crear i fer un ús correcte de les taules de la base de dades creada.