SQLite Android: Crear nuestra propia Base de Datos externa y copiarla a nuestra aplicación

Hola de nuevo! Aquí aprenderás a crear una Base de Datos de forma externa es decir con una aplicación que no tiene nada que ver con Android para después utilizarla en nuestra aplicación, y así tener acceso a estos datos dentro del programa que hagamos.

La primera aplicación que hice, precisamente hacia esto, necesitaba tener una Base de Datos que contara con un listado de restaurantes en España que aceptara Ticket Restaurante, y que me mostrara los restaurantes en base a tu ubicación y que te mostrara los que tuvieras mas cerca puedes ver la aplicación aquí

En mis comienzos, y cuando me toco buscar información sobre esto, no encontré en ningún tutorial, información clara sobre este tema, y lo que encontraba no me funcionaba ¿por que? por que mi Base de Datos ocupaba 8Mb, y todo lo que encontraba era para copiar bases de datos de menos de 1Mb ¿por que? pues es una limitación que hay en Android en copar ficheros de mas de 1Mb desde el directorio assets o raw, es una mierda, pero es así.

Así. que la primera gran conclusión y la que mas dolores de cabeza me dio en su momento es que el tamaño de la Base de datos resultante IMPORTA.

¿Donde esta el limite? pues como dije antes en 1Mb, con menos de 1Mb no hay ningún problema, copiamos la base de datos resultante al proyecto y ejecutamos el código en la clase SQLiteOpenHelper y LISTO!, con mas de 1Mb tenemos que "partir" el fichero resultante de la Base de Datos en fragmentos de 1Mb, para luego recomponerla en nuestra aplicación, este proceso de "partir" la base de datos es lo complicado, tendremos que usar un comando "split" que solo esta en sistemas operativos Linux, por eso es la complejidad de este asunto, pero bueno, no te preocupes!! porque en el próximo tutorial te explicare paso a paso como descargar linux e instalarla en una máquina virtual, todo es GRATIS, así. que no te preocupes!! ahora vamos a ver como crear y copiar una base de datos de menos de 1Mb.

 

Paso 1: Creando y preparando el fichero de base de datos SQLite

Lo primero que tenemos que hacer es crear la Base de Datos, esto lo hacernos mediante un software de código abierto SQLite Database Browser disponible para Windows Mac y Linux.

Cuando lo descargemos, tan solo tienes que descomprimir el fichero y ejecutar el fichero SQLite Browser veras algo así.:

sqlite android

Pulsa sobre nuevo, te preguntara donde quieres guardar la base de datos, selecciona tu ruta (una que te sea sencilla acceder, porque luego tendremos que copiarla a nuestra aplicación de Android en Eclipse) y pulsa sobre Guardar, yo he elegido la misma carpeta donde esta el programa.

sqlite, select

Cuando le des a Guardar te preguntara si quieres crear una Tabla, cancela el dialogo y vamos al lío!

sqlite, select

Como vimos en temas anteriores, una Base de Datos Android esta compuesta por una o varias tablas en su interior, en este caso, para Android esta base de datos deberá contener una tabla con un nombre determinado y con un valor determinado, para crear las tablas mediante este programa, lo podríamos hacer, o de forma manual, usando el asistente, o mediante sentencias de SQL, para este tutorial, usaremos 2 sentencias, una para crear la tabla y otra para añadir un registro con un valor.

Paso 1.1. Crear Tabla "android_metadata"
Pulsa sobre la pestaña "Execute SQL" y pega el código que ves abajo para crear la tabla, después pulsa sobre el botón"Execute".

CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'es_ES')
sqlite, select

Si todo a salido bien, veras un mensaje "No error".

Paso 1.2. Añadir registro a la Tabla "android_metadata"
Ahora repite todos los pasos anteriores para con la siguiente línea para crear un registro con el dato‘es_ES’ en la tabla recién creada.

INSERT INTO "android_metadata" VALUES ('es_ES')

Vuelve a la pestaña de Database Structure para comprobar que este la tabla, fíjate que aquí aparecen las tablas, y si le damos al + aparecen los campos.

sqlite, select

Si queremos ver los datos que contiene la tabla, pulsa sobre Browse Data para poder visualizar los registros que hay en las Tablas.

sqlite, select

 

Paso 1.3. Crear otra nueva Tabla con tus datos y campos.
Vale! ahora debes de crear otra tabla con el nombre que tu quieras para introducir los datos que necesites, para esto puedes usar otra sentencia de SQL o utilizar el asistente que tiene la aplicación (los iconos superiores de la aplicación) es bastante intuitiva asi que no creo que tengas problemas, la ventaja de usar sentencias de SQL es que con ejecutar una simple sentencia puedes crear instantáneamente decenas de campos.

IMPORTANTE!! la tabla que crees debe tener 1 campo obligatorio.

 Nombre del campo: _id
 Tipo de campo: INTEGER PRIMARY KEY AUTOINCREMENT

a partir de aquí, pon lo que necesites, te pongo aquí el código que use para mi aplicación de los restaurantes.

CREATE TABLE restaurantes (_id INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT, lat DOUBLE, lon DOUBLE, direccion TEXT,	cp INTEGER, localidad TEXT, provincia TEXT, telefono INTEGER, tipo_comida TEXT, tipo_vale TEXT)
			  

Después de todo, es posible que la propia aplicación te añada automáticamente una tercera tabla llamada "sqlite_sequence" aquí se guardan las transacciones que se van haciendo en la base de datos NO LA BORRES dejalo así. tal cual.

sqlite, select

Paso 2: Copiar la base de datos externa a nuestra aplicación con SQLiteOpenHelper.

assests, androidEste paso es la madre del cordero! recuerda que al principio de la lección hable que había una limitación en cuanto al tamaño de la base de datos que vamos a copiar, recuerda que este tutorial y este código es es para las Bases de Datos que son menores de 1Mb, el motivo es que Android no puede leer ficheros desde la carpeta assests o raw de mas de 1Mb, por eso en la próxima lección aprenderemos a partir las bases de datos en fragmentos de 1Mb y luego re componerla en en Método de la clase SQLiteOpenHelper.

Ahora lo que tenemos que hacer es copiar el fichero resultante de crear nuestra base de datos con el SQLite Database Browser que hemos creado antes a nuestro proyecto en Eclipse.

Coge el fichero y arrastralo desde el explorador de windows a nuestro proyecto a una carpeta llamada "assets" si no existe esta carpeta la tendrás que crear tu.

El código que te pongo a continuación es el que utilice en mi aplicación para copiar el fichero de base de datos a mi aplicación, lo he modificado para adaptarlo a una base de datos de 1Mb, como te dije antes, el siguiente tutorial veremos otro código para copiar una base de datos de 8Mb, ahora tendrás que modificar varias cosas, como el nombre de la base de datos, el nombre del paquete... exactamente son estas 2 líneas:

private static String DB_PATH = "/data/data/es.epinanab.calculadoraticket/databases/";
private static String DB_NAME = "db_calc";
			

 La línea 18. Es la ruta que tienen las bases de datos, todas las Bases de datos de cada aplicación se guardan en esa ruta, tendrás que sustituir mi nombre del paquete por el tuyo es.pinanab.calculadoraticket.
 La línea 19. Es el nombre de la base de datos en tu aplicación, es decir el nombre que utilizaras en tu aplicación para acceder a la Base de Datos.


package es.epinanab.calculadoraticket;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

public class BaseDeDatos extends SQLiteOpenHelper {

	private static String DB_PATH = "/data/data/es.epinanab.calculadoraticket/databases/";
	private static String DB_NAME = "db_calc";
	private SQLiteDatabase myDataBase;
	private final Context myContext;

	public BaseDeDatos(Context contexto, String nombre, CursorFactory factory,
			int version) {

		super(contexto, nombre, factory, version);
		this.myContext = contexto;
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// No hacemos nada aqui
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// Cuando haya cambios en la estructura deberemos
	}

	public void createDataBase() throws IOException {

		boolean dbExist = checkDataBase();

		if (dbExist) {
			// Si existe, no haemos nada!
		} else {
			// Llamando a este método se crea la base de datos vacía en la ruta
			// por defecto del sistema de nuestra aplicación por lo que
			// podremos sobreescribirla con nuestra base de datos.
			this.getReadableDatabase();

			try {

				copyDataBase();

			} catch (IOException e) {

				throw new Error("Error copiando database");
			}
		}
	}

	private boolean checkDataBase() {

		SQLiteDatabase checkDB = null;

		try {
			String myPath = DB_PATH + DB_NAME;
			checkDB = SQLiteDatabase.openDatabase(myPath, null,	SQLiteDatabase.OPEN_READONLY);

		} catch (SQLiteException e) {
			// Base de datos no creada todavia
		}

		if (checkDB != null) {

			checkDB.close();
		}

		return checkDB != null ? true : false;

	}

	public void openDataBase() throws SQLException {

		// Open the database
		String myPath = DB_PATH + DB_NAME;
		myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
	}

	@Override
	public synchronized void close() {

		if (myDataBase != null)
			myDataBase.close();

		super.close();
	}

	private void copyDataBase() throws IOException {

		OutputStream databaseOutputStream = new FileOutputStream("" + DB_PATH + DB_NAME);
		InputStream databaseInputStream;

		byte[] buffer = new byte[1024];
		int length;

		databaseInputStream = myContext.getAssets().open("MiPrimeraBD");
		while ((length = databaseInputStream.read(buffer)) > 0) {
			databaseOutputStream.write(buffer);
		}

		databaseInputStream.close();
		databaseOutputStream.flush();
		databaseOutputStream.close();
	}

}

Paso 3: Poner el codigo en tu aplicacion con la que ejecutara el codigo que hemos creado en el paso 2.

El codigo que vas a ver a continuacion, deberas ponerlo solo la primera vez que intentes accedes a la base de datos por primera vez, yo te aconsejo que lo pongas seguido al OnCreate para que te asegures de que inicializas la base de datos antes de usarla mas adelante cuando te interese.

// Esto es para inicializar la BD
		BaseDeDatos db2 = new BaseDeDatos(this, DB_NAME, null, DB_VERSION);
		try {
			db2.createDataBase();
			db2.openDataBase();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			  

¿que os parece? no es complicado, como todo requiere practica y hacer varias pruebas, pero vamos si yo pude.. ¡tu también! animo y si no te aclaras, pregunta en el foro.

Si te a gustado este sitio, por favor haz click en me gusta en Facebook, Google+, Tweeter... es el único precio que te pido por este trabajo! ;P. Compartiendo, ayudaras a otros a encontrar esta web! GRACIASSSS.