70
Profesor: Edwin Martínez Hernández [email protected] PROGRAMACION DE TERMINALES MOVILES 5. SQLite Morelia, Michoacán, México. 2013

5._SQLite

Embed Size (px)

DESCRIPTION

Tutorial SQLite

Citation preview

Page 1: 5._SQLite

Profesor: Edwin Martínez Hernández

[email protected]

PROGRAMACION DE TERMINALES MOVILES

5. SQLite

Morelia, Michoacán, México. 2013

Page 2: 5._SQLite

2

Page 3: 5._SQLite

3

Page 4: 5._SQLite

4

Page 5: 5._SQLite

5

Page 6: 5._SQLite

6

Hay cuatro maneras de almacenar los datos en Android, usaremos una u otra dependiendo de la función que tengan dichos datos.

Es importante destacar que los datos de cada aplicación son privados a dicha aplicación, pero tenemos la posibilidad de compartirlos si así lo deseamos

Page 7: 5._SQLite

7

Existen cuatro tipos de datos distintos, en función de lo que queramos almacenar.

Dichos tipos son:

1. Preferencias: Conjunto de datos, clave/valor

2. Archivos locales: Almacenamiento interno y externo (SD)

3. Base de datos: SQLite

4. Proveedores de contenidos: Único mecanismo para compartir datos, no se trata con ellos directamente.

Page 8: 5._SQLite

8

Tenemos a nuestra disposición un tipo de datos llamado preferencias. Estas preferencias, son una forma ágil para poder guardar datos simples de la aplicación.

Estos datos son un conjunto clave/valor que perdura después de que la aplicación se cierre, por lo que es principalmente útil para guardar, como su nombre indica, las preferencias de una aplicación.

Por ejemplo guardar el idioma, configuraciones de sonido de la aplicación, fuentes, colores, etc.

Los datos que permite guardar son primitivos y se invocan con los siguientes métodos putInt(), putBoolean(), putFloat(), putLong(), putString(), putStringSet() de la forma (String key, tipo value).

Page 9: 5._SQLite

9

SharedPreferences

Para Guardar y acceder a los datos de las preferencias se utiliza la clase que hereda de PreferenceActivity, la cual guarda en un xml las preferencias de la aplicación que, en principio, serán cargadas cuando la iniciemos y guardadas cuando la cerremos.

Dicho xml se guarda en SharedPreferences. Es importante destacar que podemos tener una colección de preferencias, para ello tendremos que asociarles un identificador.

Almacenándose los datos en:

/data/data/nombre_paquete/shared_prefs/mis_preferencias.xml

Page 10: 5._SQLite

10

Para guardar los datos. Tenemos a nuestra disposición los métodos onSaveInstance() y onStop().

Para guardar los datos :

1. Llamamos a edit(void) para editar las preferencias con SharedPreferences.Editor.

2. Añadimos valores con los métodos put

3. Actualizamos los nuevos valores usando commit(void)

Page 11: 5._SQLite

11

private static final String PREFS_NAME = "mis_preferencias.xml";

…..

….

protected void onStop(){

super.onStop();

// Necesitamos un objeto Editor para poder modificar las preferencias

SharedPreferences preferencias = getSharedPreferences(PREFS_NAME, 0);

SharedPreferences.Editor editor = preferencias.edit();

editor.putString("NumeroAlAzar", "58472");

// Por ejemplo un número al azar

// Actualizamos las nuevas preferencias

editor.commit();

}

Page 12: 5._SQLite

12

Una vez que se tienen las preferencias guardadas, el siguiente código muestra como guardarlas:

public class PreferenciasActivity extends PreferenceActivity implements

OnSharedPreferenceChangeListener {

//... Tu código

protected void onCreate(Bundle icicle) {

super.onCreate(icicle);

// Carga las preferencias del XML.

addPreferencesFromResource(R.xml.preferencias);

getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

}

//... Tu código

}

Page 13: 5._SQLite

13

Preference Activity

Para hacer nuestras preferencias en xml.

Dichos xml se almacenan en /res/xml, y pueden constar de los siguientes tipos de opciones:

1. CheckBoxPreference: Check, valor booleano.

2. EditTextPreference: Cadena de texto.

3. ListPreference: Lista de selección única.

4. MultiSelectListPreference: Lista de selección múltiple.

Page 14: 5._SQLite

14

Codigo xml

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

<PreferenceCategory>

TU CÓDIGO DE ESTA CATEGORÍA

</PreferenceCategory>

<PreferenceCategory>

TU CÓDIGO DE ESTA CATEGORÍA

</PreferenceCategory>

</PreferenceScreen>

Page 15: 5._SQLite

15

Cuando hayamos definido nuestras preferencias, tendremos que implementar una nueva actividad, para ello tendremos que crear una clase que extienda de PreferenceActivity de la siguiente forma:

public class Opciones extends PreferenceActivity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

addPreferencesFromResource(R.xml.opciones);

}

}

Page 16: 5._SQLite

16

También tendremos que añadirla al Manifest como actividad, para ello bastará con añadir el siguiente código en el Manifest.

<activity android:name=".PantallaOpciones"

android:label="@string/app_name">

</activity>

Page 17: 5._SQLite

17

A la hora de guardar distintos tipos de datos, que no se ajusten al patrón clave/valor de las preferencias, tendremos que guardarlos como archivos locales, dichos archivos, por defecto, no son accesibles desde otras aplicaciones, regulado por permisos Unix. El acceso es parecido al de Java estándar, debemos crear tanto input stream como output stream.

Puede soportar solamente archivos creados en la carpeta de la aplicación. Por lo que necesitamos saber dónde están almacenadas las aplicaciones.

Están almacenadas en:

/data/data/nombre_paquete/files/nombre_archivo

pudiendo almacenarse en la SDCard.

Page 18: 5._SQLite

18

Para crear los output stream y los input stream, hay que destacar que en el output stream tenemos que seleccionar el modo de acceso, que puede ser:

1. MODE_PRIVATE(por defecto) acceso privado desde nuestra aplicación.

2. MODE_APPEND para poder añadir datos a un fichero existente.

3. MODE_WORLD_READABLE para permitir lectura a otras aplicaciones.

4. MODE_WORLD_WRITABLE para permitir escritura a otras aplicaciones.

Page 19: 5._SQLite

19

Código Ejemplo:

try

{

OutputStreamWriter fOut=

new OutputStreamWriter(

openFileOutput("texto_ejemplo.txt", Context.MODE_PRIVATE));

fOut.write("Cualquier cosa"); // Escribimos “Cualquier cosa” en fOut

fOut.close(); // Cerramos la escritura en el fichero fOut

}

catch (Exception e)

{

Log.e("Error de archivo", "Error al escribir el archivo.");

}

Page 20: 5._SQLite

20

para los input hay que tener en cuenta que solamente podremos leer aquellos archivos para los que tengamos permisos, el código viene detallado a continuación. try { BufferedReader fIn = new BufferedReader( new InputStreamReader( openFileInput("texto_ejemplo2.txt"))); String texto = fIn.readLine(); // Tomamos la línea de fIn fin.close(); // Salimos para guardar la línea } catch (Exception e) { Log.e("Error de Archivo", "Error al leer el Archivo"); }

Page 21: 5._SQLite

21

Otra forma de almacenar datos en la memoria interna es almacenarlo como recurso en la carpeta “/res/raw” de nuestro proyecto, en eclipse dicha carpeta no se crea por defecto, tendremos que crearla.

Es importante destacar que este método de almacenamiento es útil para archivos que no vamos a modificar, ya que posteriormente serán de solo lectura.

La forma de acceder a dichos archivos viene detallada a continuación.

Page 22: 5._SQLite

22

try

{

InputStream fRaw =

getResources().openRawResource(R.raw.ejemplo_raw);

//ejemplo_raw es el nombre del fichero

BufferedReader bRIn =

new BufferedReader(new InputStreamReader(fRaw));

String linea = bRIn.readLine();

fRaw.close();

}

catch (Exception e)

{

Log.e("Error de Archivo", "Error al leer Archivo desde recurso");

}

Page 23: 5._SQLite

23

La última alternativa para almacenar archivos locales será la de guardarlos en la memoria externa, que generalmente será una tarjeta de memoria SD.

Es importante destacar que en el caso de la memoria externa, y al contrario que con la memoria interna, puede no estar disponible ya sea porque no está presente o porque el dispositivo no la reconoce.

Por esto tenemos que cerciorarnos de que está disponible antes de utilizarla como sistema de almacenamiento, con ese fin usaremos el método getExternalStorageStatus() que nos devuelve el estado de la memoria externa.

Page 24: 5._SQLite

24

Según queramos leer o escribir en ella los estados que nos interesarán son:

MEDIA_MOUNTED que nos dice que podemos escribir y leer en ella

MEDIA_MOUNTED_READ_ONLY que nos dice que está disponible con permisos de solo lectura.

El siguiente fragmento de código nos muestra una forma sencilla de verificar el estado de la memoria externa y almacenarlo en dos booleanos.

Page 25: 5._SQLite

25

boolean tarjetaDisponible = false;

boolean tarjetaEscritura = false;

//Comprobamos el estado de la memoria externa (tarjeta SD)

String estadoTarjeta = Environment.getExternalStorageState();

if (estadoTarjeta.equals(Environment.MEDIA_MOUNTED)){

// Tarjeta disponible y habilitada para escritura

tarjetaDisponible = true;

tarjetaEscritura = true;

}

else if (estadoTarjeta.equals(Environment.MEDIA_MOUNTED_READ_ONLY)){

// Tarjeta disponible y deshabilitada para escritura

tarjetaDisponible = true;

tarjetaEscritura = false;

}

else{

// Tarjeta NO disponible

tarjetaDisponible = false;

tarjetaEscritura = false;

}

Page 26: 5._SQLite

26

También tendremos que indicar en el manifest que nuestra aplicación necesita permisos para almacenar datos en memoria externa, para ello pondremos:

Codigo XML

<uses-permission android.permission.WRITE_EXTERNAL_STORAGE> </uses-permission>

Page 27: 5._SQLite

27

Ahora que sabemos el estado de la memoria externa y tenemos permisos vamos a ver la ruta absoluta de la tarjeta de memoria.

Para ello usaremos el método getExternalStorageDirectory() que nos devolverá un File, ahora ya podremos crear un archivo en la dirección de dicho File como se muestra

Page 28: 5._SQLite

28

try{

File ruta_tarjeta = Environment.getExternalStorageDirectory();

File f = new File(ruta_tarjeta.getAbsolutePath(), "ejemplo_tarjeta.txt");

OutputStreamWriter fOut =

new OutputStreamWriter(

new FileOutputStream(f));

fOut.write(«Sonrie!! :D.");

fOut.close();

}

catch (Exception e){

Log.e("Error de Archivos", "Error al escribir Archivo en la tarjeta.");

}

Page 29: 5._SQLite

29

Para leer de un archivo el código es muy similar a la escritura

try{

File ruta_tarjeta = Environment.getExternalStorageDirectory();

File f = new File(ruta_tarjeta.getAbsolutePath(), "ejemplo_tarjeta.txt");

BufferedReader fIn =

new BufferedReader(

new InputStreamReader(

new FileInputStream(f)));

String linea = fIn.readLine();

fIn.close();

}

catch (Exception e){

Log.e("Error de Archivos", "Error al leer Archivo de la tarjeta.");

}

Page 30: 5._SQLite

30

Android tiene integrado en el propio sistema una API completa que nos permite manejar BD en SQLite. SQLite es un motor de bases de datos que se ha ido popularizando en los últimos años dado que maneja archivos de poco tamaño, no necesita ejecutarse en un servidor, cumple el estándar SQL-92 y, además, es de código libre.

El conjunto de la base de datos (definiciones, tablas, índices, y los propios datos), son guardados como un único fichero en la máquina host. Este diseño simple se logra bloqueando todo el fichero de base de datos al principio de cada transacción. Esta es, al mismo tiempo, su gran virtud y su mayor inconveniente, ya que gracias a ello dispone de unas latencias muy bajas, pero también impide el acceso múltiple a la base de datos.

Page 31: 5._SQLite

31

Características

Base de datos relacional para sistemas embebidos

Ocupa únicamente unos 225KB en memoria

No se trata de un proceso, sino de una librería que se añade dinámicamente a las aplicaciones que quieren utilizar SQLite

Implementa la mayor parte del estándar SQL--‐92, pero con restricciones

Soporte para ALTER_TABLE limitado

Las columnas no tienen tipos

Page 32: 5._SQLite

32

Android soporta sqlite3, la manera más fácil de acceder a la información de una base de datos local es creando una clase que herede de SQLiteOpenHelper sobre la cual tendremos que adaptar/sobreescribir los métodos proporcionados para obtener la funcionalidad con la base de datos deseada.

Básicamente en esta clase definimos los atributos de nuestra base de datos y el comportamiento ante creación y actualización de la misma.

Los métodos que deberemos sobrescribir serán onCreate() y onUpgrade(), además del constructor, donde podremos incluir todo lo que creamos necesario.

Page 33: 5._SQLite

33

El Siguiente es un ejemplo de como crear una base de datos de una entidad Domicilio que incluirá como atributos: calle, ciudad, CP y número. Crenado la clase DomicilioSQLiteHelper:

public class DomicilioSQLiteHelper extends SQLiteOpenHelper {

//Aqui creamos el String que creará la base de datos en el onCreate

String creaBD= "CREATE TABLE Domicilio (calle TEXT, ciudad TEXT, CP INTEGER, numero INTEGER)";

public DomicilioSQLiteHelper(Context context, String nombre, CursorFactory factory, int version) {

super(context, nombre, factory, version);

}

@Override

public void onCreate(SQLiteDatabase db) {

//Aqui se crea la BD, se llamaría solo cuando no exista

db.execSQL(sqlCreate);

}

@Override

public void onUpgrade(SQLiteDatabase db, int a, int b) {

/*Utilizamos como opción de actualización la de borrado de la tabla

anterior, para luego crearla vacia con la nueva versión*/

db.execSQL("DROP TABLE IF EXISTS Domicilio"); //Borrado anterior

db.execSQL(sqlCreate); //Creación nueva

}

}

Page 34: 5._SQLite

34

Cabe mencionar cuando se usarán los dos métodos anteriores, el método onCreate() se ejecutará de maneara automática cuando se necesite crear la base de datos, lo que se reduce a cualquier llamada o referencia a la base de datos mientras esta todavía no exista.

Y el método onUpgrade() que también será llamado automáticamente cuando se produzca un cambio en la estructura de la base de datos, como podría ser la inclusión/eliminación de un campo en una tabla, en el código de ejemplo anterior hemos simplemente borrado la tabla anterior y creado una tabla nueva vacía

Teniendo nuestra clase heredada SQLiteOpenHelper, estamos en disposición de utilizar los métodos getReadableDatabase() o getWritableDatabase() para acceder a la base de datos en modo lectura o lectura/escritura.

Page 35: 5._SQLite

35

Int version = 1;

String nombreDB = “DomiciliosDB”;

/****** Nuestro código anterior aquí *******/

DomicilioSQLiteHelper domicilioHelper =

new UsuariosSQLiteHelper(this, nombreDB, null, version);

// Abrimos la Base de datos, en casa de que no existiera, se crearía ahora

SQLiteDatabase db = domicilioHelper.getWritableDatabase();

//Insertamos 2 domicilios para inicializar la tabla

db.execSQL("INSERT INTO Domicilio(calle, ciudad, CP, numero) VALUES (‘C/Mayor’, ‘Madrid’, 28001, 13)");

db.execSQL("INSERT INTO Domicilio(calle, ciudad, CP, numero) VALUES (‘Avda. Grande’, ‘Ibiza’, 26050, 45)");

//Cerramos la base de datos ya actualizada

db.close();

/****** Resto de código *******/

Page 36: 5._SQLite

36

Las funciones mas comunes de una base de datos en modo escritura son:

Insertar un registro

db.execSQL("INSERT INTO Usuarios (usuario,email) VALUES ('usu1','[email protected]') ");

Eliminar un registro

db.execSQL("DELETE FROM Usuarios WHERE usuario='usu1' ");

Actualizar un registro

db.execSQL("UPDATE Usuarios SET email='[email protected]' WHERE usuario='usu1' ");

Page 37: 5._SQLite

37

Cursores

Los cursores sirven para recorrer el resultado de una base de datos como un iterador.

Para ejecutar consultas sobre la clase domicilio, para ello, los permisos con los que abriremos la base de datos de los domicilios serán sólo de lectura.

Page 38: 5._SQLite

38

Int version = 1;

String nombreDB = “DomiciliosDB”;

/****** Nuestro código anterior aquí *******/

DomicilioSQLiteHelper domicilioHelper = new UsuariosSQLiteHelper(this, nombreDB,

null, version);

// Abrimos la Base de datos, en casa de que no existiera, se crearía ahora

SQLiteDatabase db = domicilioHelper.getReadableDatabase();

Cursor c = db.rawQuery("SELECT ciudad, CP FROM Domicilio WHERE calle=“Av. Madero");

//Obtenemos los indices de las columnas

int ciudadIndex = mCursor.getColumnIndexOrThrow(“ciudad”);

int CPIndex = mCursor.getColumnIndexOrThrow(“CP”);

// Posicionamos el cursor al principio de la lista

if (c.moveToFirst()) {

do {

//Obtenemos en nuestras variables los datos del registro que está leyendo.

String ciudad= c.getString(ciudadIndex);

int CP = c.getString(CPIndex);

} while(c.moveToNext());

/****** Resto de código *******/

Page 39: 5._SQLite

39

Los Content Providers son el mecanismo que tiene Android para comunicar datos entre distintas aplicaciones. Funcionalmente suelen ser muy parecidos a las bases de datos en SQLite.

El propio Android trae (desde sus versiones 2.0+) incluidos la agenda ,los SMS y el listado de llamadas mediante el método de los Content Providers, simplemente una aplicación debe acceder a la URI donde tenemos el Content Provider y una vez tengamos acceso pedirle los datos que necesitemos.

Page 40: 5._SQLite

40

Al igual que para las bases de SQLite para los Content Providers deberemos crear una clase que herede de ContentProvider y declararla en el manifest.

<application>....

<provider android:name="DomiciliosProvider"

android:authorities="com.pruebasandroid.ejemplo" />

<application/>

Page 41: 5._SQLite

41

La facilidad de su uso reside en tener una base de datos que realice las mismas funciones que los métodos que tenemos que sobreescribir, para llamarlos basta con hacer un buen uso de las URIs.

A continuación se muestra el código, a modo de ejemplo, de DomiciliosProvider:

Page 42: 5._SQLite

42

package com.pruebasandroid.ejemplo;

public class DomiciliosProvider extends ContentProvider {

//Establecemos como una constante la URI para acceder a estos datos

private static final String uri = "content://com.pruebasandroid.ejemplo/domicilios";

//Uri del String anterior

public static final Uri CONTENT_URI = Uri.parse(uri);

//Necesario para UriMatcher

private static final int DOMICILIOS = 1;

private static final int DOMICILIOS_ID = 2;

private static final UriMatcher uriMatcher;

//Clase interna para declarar las constantes de columna

public static final class Clientes implements BaseColumns{

private Clientes() {}

// Inicializamos las columas, para poder acceder a ellas con un mnemotécnico

public static final String COL_CALLE = "calle";

public static final String COL_CP = "cp";

public static final String COL_NUMERO = "numero";

public static final String COL_CIUDAD = "ciudad”;

}

Page 43: 5._SQLite

43

//Los datos referentes a la base de datos, que creamos en el ejemplo anterior

private UsuariosSQLiteHelper helper;

private static final String NOMBRE_BD = "DomicilioDB";

private static final int VERSION = 1;

private static final String TABLA_DOMICILIOS = "Domicilios";

//Inicializamos el UriMatcher

static {

uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

uriMatcher.addURI("com.pruebasandroid.ejemplo", "domicilios", DOMICILIOS);

uriMatcher.addURI("com.pruebasandroid.ejemplo", "domicilios/#",

DOMICILIOS_ID);

}

/*Sobreescribimos los métodos de ContentProvider*/

@Override

public boolean onCreate() {

helper = new UsuariosSQLiteHelper(

this.getContext(), NOMBRE_DB, null, VERSION);

return true;

}

Page 44: 5._SQLite

44

/*Aqui devolvemos el cursor de nuestra BD de domicilios*/

@Override

public Cursor query(Uri uri, String[] projection,

String selection, String[] selectionArgs, String sortOrder) {

/*Construimos un where si se refiere a un id concreto */

String where = selection;

if(uriMatcher.match(uri) == DOMICILIOS_ID){

where = "_id=" + uri.getLastPathSegment();

}

/*Escritura y lectura y devolvemos el cursor de nuestra base de datos*/

SQLiteDatabase db = helper.getWritableDatabase();

return (Cursor)db.query(TABLA_DOMICILIOS, projection, where,

selectionArgs, null, null, sortOrder);

}

@Override

public Uri insert(Uri uri, ContentValues values) {

/*para escribir, insertamos en la base de datos que nos proporciona*/

long id = 1;

SQLiteDatabase db = helper.getWritableDatabase()

id = db.insert(TABLA_DOMICILIOS, null, values);

Page 45: 5._SQLite

45

/*Devolvemos su correspondiente Uri*/

Uri newUri = ContentUris.withAppendedId(CONTENT_URI, id);

return newUri;

}

@Override

public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {

/* Aqui el código para el update*/

}

@Override

public int delete(Uri uri, String selection, String[] selectionArgs) {

/* Aqui el código para el delete*/

}

Page 46: 5._SQLite

46

@Override

public String getType(Uri uri) {

int tipo = uriMatcher.match(uri);

switch (tipo){

case DOMICLIOS:

return "vnd.android.cursor.dir/vnd.pruebasandroid.domicilio";

case DOMICILIOS_ID:

return "vnd.android.cursor.item/vnd.pruebasandroid.domicilio"";

default:

return null;

}

}

}

Page 47: 5._SQLite

47

Ahora empezaremos a trabajar con SQLite, con el interpretes de comandos que el ADB (Android Debug Bridge) nos brinda para conectar con un dispositivo virtual de Android e interactuar con el mediante un shell de linux.

Iniciar sqlite3

1. Usando el AVD Manager o desde Eclipse, comenzaremos iniciando un dispositivo virtual de Android

2. Después abriremos una ventana de comandos de msdos y debemos posicionarnos en el directorio platform-tools, localizado donde tenemos instalado el android-sdk

Page 48: 5._SQLite

48

3. Utilizamos el comando adb shell para conectar con la terminal

El simbolo # es el prompt, e indica que hemos conectado con nuestro emulador y hemos iniciado una sesion de Linux.

Si hay un telefono o dispositivo conectado, hay que especificar donde queremos conectarnos, si al emulador o al telefono, mediante adb –e shell (emulador) o adb –d shell (dispositivo).

Y podemos empezar a introducir comandos en linux

Page 49: 5._SQLite

49

4. Nos situamos en el directorio data y ahí creamos un directorio pruebas para trabajar

5. Una vez en el directorio pruebas, iniciamos SQLite creando una base de datos, esta base de datos la almacenamos en un archivo base.db

Page 50: 5._SQLite

50

SQLite permite ejecutar una serie de comandos que comienzan por un punto.

Se puede ver una lista de comandos disponibles introduciendo el comando .help, .exit lo utilizamos para salir

Page 51: 5._SQLite

51

Crear una tabla

Crearemos una tabla para nuestra Biblioteca mediante la sentencia create de SQL.

Para ver la lista de tablas, se usa el comando .tables

Los tipos de datos mas comunes son text, integer y float

Page 52: 5._SQLite

52

Para ver la definición de una tabla usamos el comando .schema

Para introducir los datos utilizamos insert

Para comprobar el contenido de la tabla

Page 53: 5._SQLite

53

Para cambiar el modo de visualización podemos usar .mode column

Page 54: 5._SQLite

54

//Este es el codigo de la clase adicional para manejar la base de datos package com.example.basedatosbibliotecaii; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class ManejaBaseDatos extends SQLiteOpenHelper { private static final String NOMBRE_BASE="BibliotecaII.db"; public static final String ID="id"; public static final String NOMBRE_LIBRO="nombreLibro"; public static final String NOMBRE_AUTOR="autor"; public static final String EDITORIAL="editorial"; public static final String ISBN="ISBN"; private static final int VERSION=1; public ManejaBaseDatos(Context context){ super(context, NOMBRE_BASE, null, VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE TablaLibros (id integer primary key autoincrement, nombreLibro text, autor text, editorial text ,ISBN text);"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS TablaLibros;"); onCreate(db); } }

Page 55: 5._SQLite

55

import android.os.Bundle; import android.app.Activity; import android.content.ComponentName; import android.content.ContentValues; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.view.Menu; import android.view.View; import android.widget.TextView; public class AltasActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_altas); } public void clickAceptar(View btn){ TextView nombreLibro=(TextView) findViewById(R.id.txtNombreLibro); TextView autor=(TextView) findViewById(R.id.txtNombreAutor); TextView editorial=(TextView) findViewById(R.id.txtEditorial); TextView ISBN=(TextView) findViewById(R.id.txtISBN); inserta(nombreLibro.getText().toString(),autor.getText().toString(),editorial.getText().toString(),ISBN.getText().toString()); } public void inserta(String nombreLibro, String autor, String editorial, String ISBN){ ManejaBaseDatos manejadb= new ManejaBaseDatos(this); SQLiteDatabase db=manejadb.getWritableDatabase(); ContentValues cv=new ContentValues(); cv.put(manejadb.NOMBRE_LIBRO, nombreLibro); cv.put(manejadb.NOMBRE_AUTOR, autor); cv.put(manejadb.EDITORIAL, editorial); cv.put(manejadb.ISBN, ISBN); db.insert("TablaLibros", manejadb.NOMBRE_LIBRO, cv); db.close(); /*String cadenavalues="(values('"+nombreLibro+"','"+autor+"','"+editorial+"','"+"','"+ISBN+"')"; db.execSQL("insert into TablaLibros (nombreLibro,autor,editorial,ISBN"+cadenavalues+") ;");*/ }

Page 56: 5._SQLite

56

https://addons.mozilla.org/es/firefox/addon/sqlite-manager/

Page 57: 5._SQLite

57

Para realizar una consulta se usa el metodo RawQuery, que

devuelve un objeto de tipo Cursor

Para escribir todos los elementos todos los elementos de la tabla

escribiriamos:

Cursor cursor=db.rawQuery("select * from TablaLibros",null);

El objeto Cursor contiene el resultado de la busqueda, ademas de

información sobre las filas y las columnas de las tabla.

Para extraer el contenido de la primera fila, primero hay que colocar

el cursor en el primer registro utilizando el metodo moveToFirst()

Page 58: 5._SQLite

58

Para extraer las columnas almacenadas en el Cursor se utiliza el

método getInt(i) o getString(i), dependiendo del tipo de datos que

contenga la columna (i).

Una vez que se obtienen los elementos solicitados, nos podemos

mover al siguiente registro con el método moveToNext() y se

procede del mismo modo.

El metodo moveToNext() devuelve false si el Cursor está situado

en la última fila y true en caso contrario.

El número de filas contenidas en el Cursor se obtiene con

getCount() y el número de columnas con getColumnCount()

Page 59: 5._SQLite

59

//Codigo para hacer las consultas de una tabla

Cursor cursor=db.rawQuery("select * from TablaLibros",null);

if(cursor.moveToFirst()==true){

Toast toast1 = Toast.makeText(getApplicationContext(),"Existen "+ cursor.getCount()+" Libros en la

Biblioteca", Toast.LENGTH_SHORT);

toast1.show();

for(int i=1;i<cursor.getCount();i++){

int var_id=cursor.getInt(0);

String var_nLibro=cursor.getString(1);

String var_nAutor=cursor.getString(2);

String var_editorial=cursor.getString(3);

String var_ISBN=cursor.getString(4);

toast1= Toast.makeText(getApplicationContext(),"Id "+ var_id+" Nombre

Libro:"+var_nLibro+" Nombre Autor:"+var_nAutor+" Editorial:"+ var_editorial+"

ISBN:"+var_ISBN, Toast.LENGTH_SHORT);

cursor.moveToNext();

}

}else{

Toast toast1 = Toast.makeText(getApplicationContext(),"No hay Datos en la Biblioteca",

Toast.LENGTH_SHORT);

toast1.show();

}

Page 60: 5._SQLite

60

Para borrar filas de una tabla se puede utilizar el método

execSQL(), en donde el parámetro debe de tener el o los registros a

eliminar dentro de la tabla correspondiente.

Ejemplo

db.execSQL("delete from TablaLibros where id=1;");

Page 61: 5._SQLite

61

El método query() de la clase SQLiteOpenHelper, requiere siete

parametros necesarios para realizar una consulta completa SQL

public Cursor query(String table, String[] columns, String selection,

String[] selectionArgs, String groupBy, String having, String

orderBy)

Para buscar todas las columnas y filas de una tabla, similar a un

select * from TablaLibro, solo de debe de proporcionar el primer

parametro que es el nombre de la tabla, quedando la instrucción de

la siguiente forma:

Cursor cursor=db.query("TablaLibros",null,null,null,null,null,null);

Page 62: 5._SQLite

62

Otro ejemplo para utilizar el metodo query seria el siguiente:

String[] columns={"nombreLibro","nombreAutor"};

String "id>10";

String selectionArgs=null;

String groupBy=null;

String having=null;

String orderBy="id";

cursor=

db.query("TablaLibros",columns,selection,selectionArgs,groupBy,

having,orderBy);

Page 63: 5._SQLite

63

El método delete() de la clase SQLiteOpenHelper, se utiliza para

eliminar registros de una tabla y requiere tres parametros el primero

el nombre de la tabla, el segundo la condicion where de los registros

a borrar y el tercero regularmente se utiliza null

Ejemplo

db.delete("TablaLibros","id>1",null);

Que es equivalente a:

delete from operas where id>1;

Page 64: 5._SQLite

64

La Clase CursorAdapter permite adaptar un Cursor a un ListView y

así mostrar en una lista de items los resultados de búsqueda de una

base de datos.

con la clase SimpleCursorAdapter se pueden especificar las

columnas que se desean mostrar, asociando cada una de las

columnas a un TextView.

El ListView se asocia a su vez a su vez al layout de un archivo xml,

que contiene los distintos TextView.

Para construir un SimpleCursorAdapter se requieren cinco

argumentos

Page 65: 5._SQLite

65

String[] from={"nombreLibro","nombreAutor"};

int[] to={R.id.nLibro,R.id.nAutor};

SimpleCursorAdapter adapter=new SimpleCursor

(this,R.layout.list,cursor,from,to);

El primer parametro es el contexto, es decir la actividad actual, this

El segundo es el identificador del layout correspondiente al archivo

list.xml

El tercero es el cursor que necesariamente debe de tener una

columna _id (en caso contrario se produce un error).

El cuarto elemento es un arreglo de cadenas que contienen las

columnas del cursor que se quieran escribir

El ultimo elemento es un arreglo de enteros que contienen los id de

los TextView

Page 66: 5._SQLite

66

public class ListaConsultasActivity extends Activity {

TextView txtnombreLibro, txtnombreAutor;

ManejaBaseDatos manejadb= new ManejaBaseDatos(this);

SQLiteDatabase db=manejadb.getReadableDatabase();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_lista_consultas);

txtnombreLibro=(TextView) findViewById(R.id.txtNombreLibro);

txtnombreAutor=(TextView) findViewById(R.id.txtNombreAutor);

//Realiza la busqueda

String [] columns={"_id","nombreLibro","nombreAutor"};

Cursor cursor=db.query("TablaLibros",columns,null,null,null,null,null);

//adapta el cursor al ListView

ListView lv=(ListView) findViewById(R.id.listView1);

String[] from={"nombreLibro","nombreAutor"};

int[] to={R.id.txtNombreLibro,R.id.txtNombreAutor};

SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.activity_lista_consultas,cursor,from,to);

lv.setAdapter(adapter);

lv.setOnItemClickListener((OnItemClickListener) this);

db.close();

}

public void onItemClick(AdapterView<?> listView, View v, int position, long id){

Cursor cursor=(Cursor) listView.getItemAtPosition(position);

int _id=cursor.getInt(0);

String nL=cursor.getString(1);

String nA=cursor.getString(2);

txtnombreLibro.setText(nL);

txtnombreAutor.setText(nA);

}

}

Page 67: 5._SQLite

67

Las Bases de Datos SQLite son internas a cada aplicación. Para que

nuestra base de datos u otros contenidos sean accesibles, se debe de

crear un proveedor de contenidos, extendiendo la clase

ContentProvider.

Android utiliza proveedores de contenidos nativos para almacenar

los contactos, las imágenes, los archivos multimedia, las

preferencias, las llamadas telefónicas, etc.

Cada ContentProvider posee un identificador unico, especificado

mediante una cadena de texto en formato URI (Uniform Resource

Location). Este identificador uniforme de recurso tiene una

estructura similar al URL(Uniform Resource Location) de una

pagina Web.

Page 68: 5._SQLite

68

La URI de la tabla de contactos de Android es

content://com.android.contacts/contacts

Esta URI consta de varias partes:

• El prefijo content es obligatorio e indica que se trata del URI de

un Content Provider.

• La autoridad (authority) //com.android.contacts identifica al

proveedor de contactos. Este Nombre corresponde a una

aplicación Android que nos da acceso a la base de datos que

contiene.

• El path /contacts o ruta del contenido, que generalmente es el

nombre de una tabla en la base de datos

Page 69: 5._SQLite

69

El URI de la tabla de contactos esta almacenado en una constante

estatica de la clase ContactsConstract. Esta clase contiene toda la

informacion y facilita el uso del proveedor de contactos. Este URI

se almacena en un objeto de tipo Uri, mediante:

Uri uriContactos=ContactsConstract.Contacts.CONTENT_URI;

Alternativamente si conocemos el URI completo, se puede utilizar

el metodo URI.parse

uriContactos=UriParse("content://com.android.contacts/contacts/17");

Page 70: 5._SQLite

70

Analisis Ejercicios Libro

En Parejas

http://www.ugr.es/~amaro/android/book2.html