Demo. Bases de datos en Android con SQLite


Te has preguntado alguna vez, ¿Cómo las Apps guardan los datos en nuestros dispositivos? ¿Qué hacer para realizar una App que guarde los cumpleaños o números de teléfonos?

La respuesta a estas preguntas radica en las Bases de Datos (BD). En Android existen varias formas de guardar datos para su uso posterior por medio de BD, entre estas formas tenemos:

  • Guardar la BD directamente en el dispositivo de forma local con SQLite (Sistema de Gestión de bases de datos relacional, contenida en una pequeña biblioteca escrita en C, que está implementada de forma nativa en Android). No es un sistema de gestión como los que estamos acostumbrados a ver que funciona Cliente-Servidor sino que la biblioteca se enlaza con el programa pasando a ser integral del mismo.
  • Crear la BD en una PC con el clásico MySQL o cualquier servidor de BD y desde la App conectarse a ella, haciendo uso de los scripts del lenguaje PHP.

Ambas formas son usadas en la actualidad, la primera es una de las más usadas, pero todo depende de lo que se quiera lograr. Ejemplo: si se quiere crear una agenda, la BD local sería la indicada, por otro lado una App que interactúe con un sitio, lo más lógico es que la BD esté fuera del dispositivo y se acceda de forma remota.

A continuación se muestra un ejemplo del trabajo en Android con SQLite, donde el usuario entrará su nombre, apellido y edad, para guardarlos en una BD y luego acceder a estos datos por medio de otra funcionalidad.

Manos a la obra

Lo primero será crear un proyecto en el ADT, ir a la parte del visual e incluir tres EditText para introducir los datos, un botón para ejecutar la acción de insertarlos y otro para consultarlos.

Interfaz visual de la app

Fig1: Interfaz visual de la app

Es necesario crear varias clases para poder tener organizado el trabajo. Para crear una nueva clase pulsar clic derecho sobre el paquete java New/Class, se abre una ventana donde se introduce el nombre de la clase y posteriormente pulsar en el botón Finish.

Para este caso se crearon 2 clases nuevas:

  • BaseDatos.java: Contiene los métodos para crear y acceder a la BD.
  • Persona.java: Utiliza la clase anteriormente creada en los métodos de insertar y consultar.
Clases del proyecto

Fig2: Clases del proyecto

Implementación de las clases

Clase BaseDatos.java:

/*
Lo primero es decirle a la clase que extienda (herede) de SQLiteOpenHelper, esta clase hereda los métodos necesarios para crear y actualizar la BD.
*/

public class BaseDatos extends SQLiteOpenHelper {

/*
Se implementa el constructor de la clase, lo único que se necesita saber es el contexto donde estamos, es por ello que este se pasa por parámetro (Context context). 
Destacar el significado de los datos que se pasan por parámetro al super de la clase padre, el primero es el contexto ya obtenido por parámetro, después el nombre del fichero que contiene la Base de Datos y los demás parámetros no serán de interés, los ponemos por defecto null y 1
*/
	public BaseDatos(Context context) {
		super(context, "myPrimera.db", null, 1);
	}	

/*
Este método solo se va a llamar la primera vez que se crea la BD, de existir, no ejecuta el evento onCreate y salta para el evento onUpgrade, por eso no nos importa este método ya que una vez creada la BD no se va a tocar más. 

Se crea de antemano la tabla Persona escribiendo su código correspondiente en lenguaje SQL y después mediante la función execSQL(<código SQL>) se ejecuta ese código dentro de la BD. 
Notar que mediante esta forma podemos escribir tantas líneas SQL deseemos y después ejecutarlas.
*/

	@Override
	public void onCreate(SQLiteDatabase db) {
	    String sql="Create table persona(nombre Text, apellido Text, edad Integer);";
	    db.execSQL(sql);
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2){
	    // Este código se ejecuta si ya está creada la BD 
	    // por eso no es necesario hacer ninguna operación aquí. 		
	}

}

Clase Persona.java:

public class Persona {

/*
Se declara una variable de tipo Context (Contexto de ejecución), una de tipo BaseDatos (clase anterior) y otra de tipo SQLiteDatabase, este objeto es la base de datos en sí y sobre él es donde está el método de insertar.
*/
	Context contextoEjecucion;
	BaseDatos creador;
	SQLiteDatabase mDatos;

/*
Constructor de la clase donde pedimos el contexto que luego nos va a servir para pasárselo a la variable creador.
*/
	public Persona(Context c) {
	    contextoEjecucion = c;
	}

/*
En este método creamos la BD si es la primera vez que se ejecuta la App. Luego le damos una instancia de escritura (getWritableDatabase) al objeto de tipo SQLiteDatabase(mDatos) para poder insertarle datos más adelante, el return no importa, podemos poner el método void y desecharlo
*/

	public Persona abrirSqlite() {
	    creador = new BaseDatos(contextoEjecucion);
	    mDatos = creador.getWritableDatabase();
	    return this;
	}

/*
Para insertar en la BD se pasan los valores deseados por parámetro: nombre, apellido y edad, se almacenan en un ContentValues(Tipo de dato donde podemos almacenar valores en parejas de llave-valor), que le suministramos por el método put("id", valor) el id de la fila de la tabla y lo que se quiere almacenar en ese campo.
En este caso es put("nombre", nombre). Finalmente se inserta el ContentValues en la BD con el método insert("tabla",null, ContentValues) de la variable mDatos creado anteriormente y se devuelve el valor que retorna este método para en el futuro poder validar si se insertaron correctamente los valores en la tabla.
*/
	public long Insertar(String nombre, String apellido, int edad){
		ContentValues c = new ContentValues();
		c.put("nombre", nombre);
		c.put("apellido", apellido);
		c.put("edad", edad);

		return mDatos.insert("persona", null, c);
	}

/*
Para comprobar si se insertaron correctamente en la BD, creé un método que devuelve en forma de cadena de texto todos los datos que están almacenados en la tabla persona de la siguiente forma: Nombre+Apellido+Edad. 
Se inicializa el objeto creador ya que es posible que el usuario pulse directamente el botón Ver, sin insertar y de error por estar el objeto en null. 
Señalar aquí que aunque estamos creando un nuevo objeto, la base de datos de estar creada no se afectará, ya que el método onCreate como dije anteriormente solo se ejecute la primera vez, de ya existir ejecuta el método onUpgrade. 
Posteriormente como se va a leer de la BD pedimos una instancia de lectura (getReadableDatabase) y se lo asignamos a mDatos. 
Al ejecutar el método rawQuery("sql", null) este devuelve un Cursor que es una forma de recorrer las filas de las consultas y acceder a sus datos, moviendo el mismo hacia diferentes posiciones.
*/
	public String ver() {
		String datos = "";
		creador = new BaseDatos(contextoEjecucion);
		mDatos = creador.getReadableDatabase();
		String sql = ("Select * from persona");
		Cursor cur = mDatos.rawQuery(sql, null);
		int i = 0;
		cur.moveToFirst();
		do {
			datos += cur.getString(0) + " " + cur.getString(1) + " "
					+ cur.getInt(2) + "\n";
		} while (cur.moveToNext());

		return datos;
	}

/*
Por último se crea el método para cerrar la conexión con la biblioteca SQLite
*/
	public void cerrarSqlite() {
		creador.close();
	}
}

Clase MainActivity.java:

public class MainActivity extends Activity {

/*
Se crean los objetos necesarios para capturar los componentes del visual
*/
	EditText eNombre;
	EditText eApell;
	EditText eEdad;
	TextView tVer;
	Button   insertar;
	Button   ver;

/*
Se capturan los componentes del visual gracias al ID que poseen
*/
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		insertar = (Button) findViewById(R.id.button1);
		eNombre = (EditText) findViewById(R.id.editText1);
		eApell = (EditText) findViewById(R.id.editText2);
		eEdad = (EditText) findViewById(R.id.editText3);
		tVer = (TextView) findViewById(R.id.mostrar);

	}

/*
Se capturan los datos de los campos, y se insertan utilizando los métodos creados anteriormente en la clase persona.
*/
	public void onclickInsertar(View v) {
		String nombre = eNombre.getText().toString();
		String apellido = eApell.getText().toString();
		int edad = Integer.parseInt(eEdad.getText().toString());

		Persona p = new Persona(MainActivity.this);
		p.abrirSqlite();
		p.Insertar(nombre, apellido, edad);
		p.cerrarSqlite();
	}

/*
Se muestra en el textView (Ver los datos de la tabla persona utilizando el método ver()) creado anteriormente para comprobar si funciona el método insertar
*/
	public void onclickVer(View v) {
		Persona p = new Persona(MainActivity.this);
		p.abrirSqlite();
		String datos = p.ver();
		p.cerrarSqlite();
		tVer.setText(datos);

	}
/*
Note que estos métodos se van a ejecutar al pulsar sobre los botones insertar y ver respectivamente. ¿Cómo es posible que sin agregarle un Listener funcionen?
La respuesta está en el código XML de los botones, se les agregó la propiedad android:onClick="<nombre_método>" a ambos. Los métodos tienen que ser void y tener como parámetro un objeto View.
*/

}

Conclusiones

Las Bases de Datos son muy útiles en Android pues nos permiten hacer las operaciones de persistencia de datos que necesitan el 99% de las Apps.

Como curiosidad decir que SQLite es ampliamente utilizado en el mundo, como consecuencia tiene un buen soporte y compatibilidad con los sistemas, el navegador Firefox, Adobe Photoshop, Skype entre otros programas tienen en común que usan SQLite en sus bases de datos.

Más adelante veremos cómo utilizar la segunda forma de manejar BD. Cualquier duda o sugerencia no dudes en dejar tu comentario. Sin más, te dejo el código fuente de la App para que lo examines en detalle.

Descargar Demo