Anda di halaman 1dari 137

16 - Almacenamiento en una base de

datos SQLite
Hemos visto hasta ahora dos modos de almacenar datos en forma permanente (archivos de
texto y la clase SharedPreferences), ahora veremos otra herramienta nativa de Android para
almacenar datos en una base de datos llamada SQLite.
SQLite es una base de datos Open Source, es muy popular en muchos dispositivos
pequeos, como Android.
Las ventajas que presenta utilizar SQLite es que no requiere configuracin, no tiene un
servidor de base de datos ejecutndose en un proceso separado y es relativamente simple su
empleo.

Problema:
Confeccionar un programa que permita almacenar los datos de articulos. Crear la tabla
articulos y definir los campos codigo, descripcin del articulo y precio.
El programa debe permitir:
1
2
3
4
4

Carga de articulo.
Consulta por el codigo.
Consulta por la descripcin.
Borrado de un articulo ingresando su cdigo.
Modificacin de la descripcin y el precio.

Lo primero que haremos es crear una clase que herede de SQLiteOpenHelper. Esta clase
nos permite crear la base de datos y actualizar la estructura de tablas y datos iniciales.
Para crear una nueva clase desde Android Studio procedemos a presionar el botn derecho
del mouse sobre la carpeta que contienen todos los archivo java del proyecto y
seleccionamos New - > Java Class:

En este dilogo ingresamos el nombre de nuestra clase, en nuestro ejemplo la llamaremos


AdminSQLiteOpenHelper:

Ya tenemos un nuevo archivo en nuestro proyecto:

Ahora tenemos que codificar esta clase que tiene por objetivo administrar la base de datos
que crearemos. Primero hacemos que nuestra clase herede de la clase SQLiteOpenHelper:
package ar.com.tutorialesya.proyecto019;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by diego on 16/04/2016.
*/
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper{
}

La clase SQLiteOpenHelper requiere que se implementen dos mtodos obligatoriamente


onCreate y onUpgrade, podemos hacer que el Android Studio nos ayude en su codificacin
as no tenemos que tipearlos nosotros: presionamos la teclas "ALT" y "ENTER" teniendo el
cursor sobre el nombre de la clase "AdminSQLiteOpenHelper" y nos aparece un men
donde seleccionamos "Implement Methods" y luego un dilogo donde seleccionamos los
mtodos a implementar:

Ya tenemos la clase con los dos mtodos:


package ar.com.tutorialesya.proyecto019;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by diego on 16/04/2016.
*/
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper{
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
}

Pero todava nos marca un error ya que la clase padre SQLiteOpenHelper implementa
constructores que tienen parmetros, entonces tenemos que definir el constructor en esta
clase, para ello estando el cursor sobre el nombre de la clase "AdminSQLiteOpenHelper"
presionamos nuevamente las teclas "ALT" y "Enter" y en el men contectual que aparece
seleccionamos "Create constructor matching super". Aparece un dilogo con todos los
constructores que implementa la clase padre (seleccionammos el que tiene tres parmetros):

Ahora la clase no muestra ningn error y pasaremos a implementar la creacin de la tabla


articulos dentro del mtodo onCreate:
package ar.com.tutorialesya.proyecto019;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by diego on 16/04/2016.
*/
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper{
public AdminSQLiteOpenHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table articulos(codigo int primary
key,descripcion text,precio real)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
}
}

Hemos codificado en el mtodo onCreate la creacin de la tabla articulos con los campos
codigo (que es entero y clave primaria), descripcion que es de tipo texto y precio es un
valor real. El mtodo onCreate se ejecutar una nica vez (Eventualmente si uno quiere
modificar la estructura de la tabla debemos hacerlo en el mtodo onUpgrade).
Ahora implementemos la interfaz visual para resolver nuestro problema. Debemos crear en
nuestro archivo activity_main.xml la siguiente interfaz:

Como vemos disponemos tres TextView, tres EditText y cinco Button.

El cdigo fuente de nuestro Activity es el siguiente:


package ar.com.tutorialesya.proyecto019;
import
import
import
import
import
import
import
import

android.content.ContentValues;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.support.v7.app.AppCompatActivity;
android.os.Bundle;
android.view.View;
android.widget.EditText;
android.widget.Toast;

public class MainActivity extends AppCompatActivity {


private EditText et1,et2,et3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

et1=(EditText)findViewById(R.id.editText);
et2=(EditText)findViewById(R.id.editText2);
et3=(EditText)findViewById(R.id.editText3);

public void alta(View v) {


AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();
ContentValues registro = new ContentValues();
registro.put("codigo", cod);
registro.put("descripcion", descri);
registro.put("precio", pre);
bd.insert("articulos", null, registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
Toast.makeText(this, "Se cargaron los datos del artculo",
Toast.LENGTH_SHORT).show();
}
public void consultaporcodigo(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
Cursor fila = bd.rawQuery(
"select descripcion,precio from articulos where codigo="
+ cod, null);
if (fila.moveToFirst()) {
et2.setText(fila.getString(0));

et3.setText(fila.getString(1));
} else
Toast.makeText(this, "No existe un artculo con dicho
cdigo",
}

Toast.LENGTH_SHORT).show();
bd.close();

public void consultapordescripcion(View v) {


AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String descri = et2.getText().toString();
Cursor fila = bd.rawQuery(
"select codigo,precio from articulos where descripcion='"
+ descri +"'", null);
if (fila.moveToFirst()) {
et1.setText(fila.getString(0));
et3.setText(fila.getString(1));
} else
Toast.makeText(this, "No existe un artculo con dicha
descripcin",
Toast.LENGTH_SHORT).show();
bd.close();
}
public void bajaporcodigo(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod= et1.getText().toString();
int cant = bd.delete("articulos", "codigo=" + cod, null);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
if (cant == 1)
Toast.makeText(this, "Se borr el artculo con dicho cdigo",
Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "No existe un artculo con dicho
cdigo",
Toast.LENGTH_SHORT).show();
}
public void modificacion(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();
ContentValues registro = new ContentValues();
registro.put("codigo", cod);
registro.put("descripcion", descri);
registro.put("precio", pre);

int cant = bd.update("articulos", registro, "codigo=" + cod,


null);

bd.close();
if (cant == 1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(this, "no existe un artculo con el cdigo
ingresado",
Toast.LENGTH_SHORT).show();
}
}

Recordar de inicializar la propiedad onClick de cada botn para enlazarlo con el mtodo
respectivo: "alta","consultaporcodigo","consultapordescripcion","bajaporcodigo" y
"modificacion".
1 - Alta de datos.
Cuando se presiona el botn "ALTA" se ejecuta el mtodo "alta" recordemos inicializar la
propiedad "onClick" del botn desde la ventana de visualizacin del archivo XML.
Lo primero que hacemos en este mtodo es crear un objeto de la clase que planteamos
anteriormente y le pasamos al constructor this (referencia del Activity actual),
"administracion" (es el nombre de la base de datos que crearemos en el caso que no exista)
luego pasamos null y un uno indicando que es la primer versin de la base de datos (en caso
que cambiemos la estructura o agreguemos tablas por ejemplo podemos pasar un dos en
lugar de un uno para que se ejecute el mtodo onUpgrade donde indicamos la nuestra
estructura de la base de datos)
Luego de crear un objeto de la clase AdminSqLiteOpenHelper procedemos a crear un
objeto de la clase SQLiteDataBase llamando al mtodo getWritableDatabase (la base de
datos se abre en modo lectura y escritura).
Creamos un objeto de la clase ContentValues y mediante el mtodo put inicializamos todos
tos campos a cargar.
Seguidamente llamamos al mtodo insert de la clase SQLiteDatabase pasando en el primer
parmetro el nombre de la tabla, como segundo parmetro un null y por ltimo el objeto de
la clase ContentValues ya inicializado (este mtodo es el que provoca que se inserte una
nueva fila en la tabla articulos en la base de datos llamada administracion)
Borramos seguidamente los EditText y mostramos un mensaje para que conozca el
operador que el alta de datos se efectu en forma correcta:
public void alta(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();

ContentValues registro = new ContentValues();


registro.put("codigo", cod);
registro.put("descripcion", descri);
registro.put("precio", pre);
bd.insert("articulos", null, registro);
bd.close();
et1.setText("");
et2.setText("");
et3.setText("");
Toast.makeText(this, "Se cargaron los datos del artculo",
Toast.LENGTH_SHORT).show();
}

2 - Consulta de articulo por cdigo.


Cuando se presiona el botn "CONSULTA POR CODIGO" se ejecuta el mtodo
consultaporcodigo:
public void consultaporcodigo(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
Cursor fila = bd.rawQuery(
"select descripcion,precio from articulos where codigo="
+ cod, null);
if (fila.moveToFirst()) {
et2.setText(fila.getString(0));
et3.setText(fila.getString(1));
} else
Toast.makeText(this, "No existe un artculo con dicho
cdigo",
Toast.LENGTH_SHORT).show();
bd.close();
}

En el mtodo consultaporcodigo lo primero que hacemos es crear un objeto de la clase


AdminSQLiteOpenHelper y obtener una referencia de la base de datos llamando al mtodo
getWritableDatabase.
Seguidamente definimos una variable de la clase Cursor y la inicializamos con el valor
devuelto por el mtodo llamado rawQuery.
La clase Cursos almacena en este caso una fila o cero filas (una en caso que hayamos
ingresado un codigo existente en la tabla articulos), llamamos al mtodo moveToFirst() de
la clase Cursos y retorna true en caso de existir un articulo con el codigo ingresado, en caso
contrario retorna cero.
Para recuperar los datos propiamente dichos que queremos consultar llamamos al mtodo
getString y le pasamos la posicin del campo a recuperar (comienza a numerarse en cero,
en este ejemplo la columna cero representa el campo descripcion y la columna 1 representa
el campo precio)

3 - Consulta de articulo por descripcin.


Cuando se presiona el botn "CONSULTA POR DESCRIPCION" se ejecuta el mtodo
consultapordescripcion:
public void consultapordescripcion(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String descri = et2.getText().toString();
Cursor fila = bd.rawQuery(
"select codigo,precio from articulos where descripcion='"
+ descri +"'", null);
if (fila.moveToFirst()) {
et1.setText(fila.getString(0));
et3.setText(fila.getString(1));
} else
Toast.makeText(this, "No existe un artculo con dicha
descripcin",
Toast.LENGTH_SHORT).show();
bd.close();
}

En el mtodo consultapordescripcion lo primero que hacemos es crear un objeto de la clase


AdminSQLiteOpenHelper y obtener una referencia de la base de datos llamando al mtodo
getWritableDatabase.
Seguidamente definimos una variable de la clase Cursor y la inicializamos con el valor
devuelto por el mtodo llamado rawQuery.
Es importante notar en el where de la clausula SQL hemos dispuesto comillas simples entre
el contenido de la variable descri:
"select codigo,precio from articulos where descripcion='"
+ descri +"'", null);

Esto es obligatorio para los campos de tipo text (en este caso descripcion es de tipo text)
4 - Baja o borrado de datos.
Para borrar uno o ms registros la clase SQLiteDatabase tiene un mtodo que le pasamos en
el primer parmetro el nombre de la tabla y en el segundo la condicin que debe cumplirse
para que se borre la fila de la tabla. El mtodo delete retorna un entero que indica la
cantidad de registros borrados:
public void bajaporcodigo(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod= et1.getText().toString();
int cant = bd.delete("articulos", "codigo=" + cod, null);
bd.close();

et1.setText("");
et2.setText("");
et3.setText("");
if (cant == 1)
Toast.makeText(this, "Se borr el artculo con dicho
cdigo",

Toast.LENGTH_SHORT).show();
else

Toast.makeText(this, "No existe un artculo con dicho

cdigo",

Toast.LENGTH_SHORT).show();

5 - Modificacin de datos.
En la modificacin de datos debemos crear un objeto de la clase ContentValues y mediante
el mtodo put almacenar los valores para cada campo que ser modificado. Luego se llama
al mtodo update de la clase SQLiteDatabase pasando el nombre de la tabla, el objeto de la
clase ContentValues y la condicin del where (el cuanto parmetro en este ejemplo no se lo
emplea)
public void modificacion(View v) {
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this,
"administracion", null, 1);
SQLiteDatabase bd = admin.getWritableDatabase();
String cod = et1.getText().toString();
String descri = et2.getText().toString();
String pre = et3.getText().toString();
ContentValues registro = new ContentValues();
registro.put("codigo", cod);
registro.put("descripcion", descri);
registro.put("precio", pre);
int cant = bd.update("articulos", registro, "codigo=" + cod,
null);
bd.close();
if (cant == 1)
Toast.makeText(this, "se modificaron los datos",
Toast.LENGTH_SHORT)
.show();
else
Toast.makeText(this, "no existe un artculo con el cdigo
ingresado",
Toast.LENGTH_SHORT).show();
}

Este proyecto lo puede descargar en un zip desde este enlace: proyecto019.zip

Ubicacin de la base de datos en el dispositivo


Para conocer donde se almacena fsicamente la base de datos en el dispositivo podemos
abrir el programa "Android Device Monitor" desde el men del Android Studio Tools>Android->Android Device Monitor:

Tutorial De Bases De Datos SQLite En Aplicaciones Android

James Revelo octubre 20, 2014 Datos 53 Comments

Continuando con nuestros tutoriales de desarrollo android, en esta ocasin veremos cmo
usar bases de datos en SQLite para no perder la informacin de nuestras aplicaciones
Android.
A medida que vayamos avanzando veremos la utilidad de clases como SQLiteOpenHelper,
SQLiteDatabase, Cursor, CursorAdapter y de Herramientas como sqlite3 y SQLite
Browser.
Con el fin de facilitar tu aprendizaje usaremos un ejemplo de gua, que te permitir ir la
prctica en paralelo a las teoras y conceptos estudiados. Puedes descargar los recursos
desde aqu:
Descargar Cdigo

Apyanos con una seal en tu red social favorita y consigue el cdigo completo.

Qu es SQLite?
Es un ligero motor de bases de datos de cdigo abierto, que se caracteriza por mantener el
almacenamiento de informacin persistente de forma sencilla. A diferencia de otros SGBD
como MySQL, SQL Server y Oracle DB, SQLite tiene las siguientes ventajas:

No requiere el soporte de un servidor: SQLite no ejecuta un proceso


para administrar la informacin, si no que implementa un conjunto de
libreras encargadas de la gestin.

No necesita configuracin: Libera al programador de todo tipo de


configuraciones de puertos, tamaos, ubicaciones, etc.

Usa un archivo para el esquema: Crea un archivo para el esquema


completo de una base de datos, lo que permite ahorrarse
preocupaciones de seguridad, ya que los datos de las aplicaciones
Android no pueden ser accedidos por contextos externos.

Es de Cdigo Abierto: Esta disponible al dominio pblico de los


desarrolladores al igual que sus archivos de compilacin e instrucciones
de escalabilidad.

Es por eso que SQLite es una tecnologa cmoda para los dispositivos mviles. Su
simplicidad, rapidez y usabilididad permiten un desarrollo muy amigable.
SQLite tiene ciertas limitaciones en algunas operaciones. Por ejemplo, no se puede
implementar las clausulas FULL OUTER JOIN y RIGHT OUTER JOIN. Aunque en la mayora
de casos esto no afectar, siempre habrn otras alternativas como JavaDB o MongoDB.

Para comenzar a probar nuestras bases de datos, quisiera explicarte un poco ms sobre el
ejemplo prctico que vamos a desarrollar. Se trata de una aplicacin llamada Quotilius.
Cuyo objetivo es guardar una lista de frases celebres.

Debemos almacenar el cuerpo de la frase y el autor que la trajo al mundo. El siguiente sera
un bosquejo rpido de como se vera la tabla de frases:
_id

body

author

El ignorante afirma, el sabio


duda y reflexiona

Aristteles

Hay derrotas que tienen ms


dignidad que la victoria

Jorge Luis
Borges

Si buscas resultados distintos,


no hagas siempre lo mismo

Albert
Einstein

Donde mora la libertad, all


est mi patria

Benjamin
Franklin

Ojo por ojo y todo el mundo


acabar ciego

Mahatma
Gandhi

La idea es proporcionarle al usuario la posibilidad de aadir nuevas frases desde la Action


Bar.
En este artculo asumir que tienes conocimientos bsicos en SQLite y que ya tienes claro
como disear una base de datos.

Ejemplo De Aplicacin Android Con SQLite


Quotilius se compone de dos actividades para su funcionamiento. La primera es
Main.java. Esta actividad est basada en una lista, donde ubicaremos las frases del
usuario. No definiremos su archivo de diseo debido a que ser una subclase de
ListActivity. As que usaremos el layout del sistema android.R.layout.list_content
para inflar la actividad.
Nota: Si quieres un proyecto en Android Studio completo con ms de 1000 frases en
SQLite, te recomiendo descargar la plantilla The Quotes Garden. Es un buen ejemplo,
adems de que puedes usarlo para tus propios proyectos.
La segunda actividad se llama Form , la cual cumple la funcin de formulario para ingresar
el cuerpo de la frase y el autor mediante dos Edit texts. Se ejecutar cuando presionamos el
Action Button Aadir. Observemos su previsualizacin:

La comunicacin entre ambas actividades se realiza a travs de un Intent explicito. Este nos
permite obtener los datos que el usuario ingres en Form para poder usarlos en Main e
ingresarlos en la base de datos y al mismo tiempo actualizar nuestro ListView.
Lo primero que hars ser enviar un Intent para ejecutar la actividad Form a travs de un
canal de comunicacin:
//Cdigo de envo
public final static int ADD_REQUEST_CODE = 1;
...
//Iniciando la actividad Form
Intent intent = new Intent(this, Form.class);
//Inicio de la actividad esperando un resultado
startActivityForResult(intent, ADD_REQUEST_CODE);

Una vez el usuario este en la actividad y haya presionado el botn de Guardar, devuelves
los valores de texto los EditTexts por el mismo canal hacia Main:
//Obtener los datos de los campos
EditText quoteField = (EditText) findViewById(R.id.quoteField);
EditText authorField = (EditText) findViewById(R.id.authorField);

//Nuevo Intent con Extras


Intent backData = new Intent();
backData.putExtra("body", quoteField.getText().toString());
backData.putExtra("author", authorField.getText().toString());
//Enviar la informacin
setResult(RESULT_OK, backData);

Luego recibes los datos con el mtodo onActivityResult() y realizas las operaciones
necesarias para guardar los datos en la base de datos:
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//Insertar registro en la base de datos
}
}

Hasta aqu hicimos un bosquejo rpido de la comunicacin entre ambas actividades. Si te


perdiste y an no sabes cmo funcionan los Intents, entonces visita nuestro tutorial sobre
Intents en Android para esclarecer ms este proceso de transmisin.

Crear Una Base De Datos En SQLite


Android SDK nos provee una serie de clases para administrar nuestro archivo de base de
datos en SQLite.
Normalmente cuando conectamos otro gestor de bases de datos tenemos que validar los
datos del equipo, el usuario y el esquema, pero con SQLite no se requiere nada de eso, ya
que podemos trabajar directamente sobre la base de datos.
La clase que nos permitir comunicar nuestra aplicacin con la base de datos se llama
SQLiteOpenHelper. Se trata de una clase abstracta que nos provee los mecanismos bsicos
para la relacin entre la aplicacin Android y la informacin.
Solo tienes que derivar de ella una subclase que se ajuste a tus necesidades y tendrs un
puente funcional hacia el archivo de datos.
As que implementaremos una nueva clase que extienda de SQLiteOpenHelper y la
llamaremos QuotesReaderDbHelper.
Veamos:
public class QuotesReaderDbHelper extends SQLiteOpenHelper {
public QuotesReaderDbHelper(Context context){

super(context,
DATABASE_NAME,//String name
null,//factory
DATABASE_VERSION//int version
);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Crear la base de datos
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
//Actualizar la base de datos
}
}

A continuacin la explicacin del cdigo:


Estructura del constructor de la clase SQLiteOpenHelper

Recibe el contexto con el cual se relacionar el helper. Luego invoca a super , donde se
enva el contexto y 3 parmetros adicionales:

name: String que representa el nombre del archivo con extensin .db

donde se almacenar la base de datos, que a su vez corresponde al


nombre de la base de datos.

factory: Asignamos null, por ahora no es necesario comprender el

funcionamiento de este parmetro.

version: Entero que representa la versin de la base de datos. Su valor


inicial por defecto es 1. Si en algn momento la versin es mayor se
llama al mtodo onUpgrade() para actualizar la base de datos a la nueva
versin. Si es menor, se llama a downUpgrade() para volver a una versin

previa.
onCreate()

Este mtodo es llamado automticamente cuando creamos una instancia de la clase


SQLiteOpenHelper. En su interior establecemos la creacin de las tablas y registros.
Recibe como parmetro una referencia de la clase SQLiteDataBase, la cual representa el
esquema completo de la base de datos.
Por defecto el archivo de la base de datos ser almacenado en la direccin
/data/data/<paquete>/databases/<nombre-de-la-bd>.db de nuestro dispositivo
mvil.

onUpgrade()

Es ejecutado si se identific que el usuario tiene una versin antigua de la base de datos. En
su interior estableceremos instrucciones para modificar el esquema de la base de datos,
como por ejemplo eliminar todo el esquema y recrearlo, agregar una nueva tabla, aadir
una nueva columna, etc. Recibe tres parmetros:

db: Es la instancia de SQLiteDataBase que representa la base de datos.

oldVersion: Se trata de un entero que indica la Version antigua de la

base de datos.

newVersion: Entero que se refiere a la Version Nueva de la base de

datos.

Crear Un Script O ContractClass De La Base De Datos


La forma en que una base de datos est estructurada (cantidad de tablas, registros, ndices,
etc.) y el conjunto de convenciones para nombrar sus objetos se les llama Esquema. Por lo
general el esquema inicial se guarda en un Script que nos permita recuperar las condiciones
previas en cualquier momento.
Con SQLite no es diferente, por lo que debes crear un esquema predefinido para
implementarlo a la hora de crear tu base de datos. La documentacin de Android nos
recomienda crear una clase llamada Contract Class. Esta clase guarda como constantes
todas las caractersticas de la base de datos, adems del cdigo SQL necesario para la
creacin, insercin, actualizacin, etc.
El esquema de la aplicacin Quotilius est basado en un diseo simple, el cual se compone
de una tabla que llamars Quotes con tres atributos: _id, cuerpo (body) y autor (author).
Ahora solo queda implementar ese esquema en una clase que llamaremos
QuotesDataSource:
public class QuotesDataSource {
//Metainformacin de la base de datos
public static final String QUOTES_TABLE_NAME = "Quotes";
public static final String STRING_TYPE = "text";
public static final String INT_TYPE = "integer";
//Campos de la tabla Quotes
public static class ColumnQuotes{
public static final String ID_QUOTES = BaseColumns._ID;
public static final String BODY_QUOTES = "body";
public static final String AUTHOR_QUOTES = "author";
}
//Script de Creacin de la tabla Quotes
public static final String CREATE_QUOTES_SCRIPT =

"create table "+QUOTES_TABLE_NAME+"(" +


ColumnQuotes.ID_QUOTES+" "+INT_TYPE+" primary key
autoincrement," +
ColumnQuotes.BODY_QUOTES+" "+STRING_TYPE+" not null,"
+
ColumnQuotes.AUTHOR_QUOTES+" "+STRING_TYPE+" not
null)";
//Scripts de insercin por defecto
public static final String INSERT_QUOTES_SCRIPT =
"insert into "+QUOTES_TABLE_NAME+" values(" +
"null," +
"\"El ignorante afirma, el sabio duda y
reflexiona\"," +
"\"Aristteles\")," +
"(null," +
"\"Hay derrotas que tienen mas dignidad que la
victoria\"," +
"\"Jorge Luis Borges\")," +
"(null," +
"\"Si buscas resultados distintos, no hagas siempre
lo mismo\"," +
"\"Albert Einstein\")," +
"(null," +
"\"Donde mora la libertad, all est mi patria\"," +
"\"Benjamin Franklin\")," +
"(null," +
"\"Ojo por ojo y todo el mundo acabar ciego\"," +
"\"Mahatma Gandhi\")";
private QuotesReaderDbHelper openHelper;
private SQLiteDatabase database;
public QuotesDataSource(Context context) {
//Creando una instancia hacia la base de datos
openHelper = new QuotesReaderDbHelper(context);
database = openHelper.getWritableDatabase();
}

En el anterior cdigo podemos notar los siguientes detalles:

Creamos una constante para el nombre de la tabla llamada


QUOTES_TABLE_NAME y otras dos para el tipo de datos que usaremos (
STRING_TYPE e INT_TYPE).

Creamos la clase interna ColumnQuotes para guardar el nombre de las


columnas de la tabla Quotes. En el caso del campo ID_QUOTES usamos
una constante BaseColumns._ID de Android con el valor _id.

Creamos la constante INSERT_QUOTES_INSERT tipo String para guardar una


sentencia SQL para crear la tabla.

Creamos la constante INSERT_QUOTES_SCRIPT tipo String para insertar


todos los datos inciales de nuestra tabla.

Como ves, es una clase muy completa que nos proporcionar flexibilidad al realizar
operaciones sobre la base de datos. Estas declaraciones facilitan la adaptacin del esquema
si en algn momento cambian los datos de las tablas o columnas.
Adicional a todas estas definiciones tenemos dos variables privadas: openHelper y
database. Ambas las usaremos en el constructor para acceder a la base de datos con el
mtodo getWritableDatabase(), el cual retorna en una instancia de SQLiteDatabase que
nos permitir leer y modificar la informacin de la base de datos directamente.

Crear La Base De Datos


Una vez terminado nuestro Esquema, procedemos a implementar los mtodos onCreate()
y onUpgrade() de nuestra clase QuotesReaderDbHelper:
public class QuotesReaderDbHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "Quotes.db";
public static final int DATABASE_VERSION = 1;
public QuotesReaderDbHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
//Crear la tabla Quotes
db.execSQL(QuotesDataSource.CREATE_QUOTES_SCRIPT);
//Insertar registros iniciales
db.execSQL(QuotesDataSource.INSERT_QUOTES_SCRIPT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
//Aade los cambios que se realizarn en el esquema
}
}

Lo primero que hicimos fue crear atributos de clase para el nombre de la base de datos y la
versin. Para crear la tabla Quotes llamamos al mtodo execSQL() de SQLiteDataBase.
Este mtodo ejecuta una sola sentencia SQL que no retorne en filas. Por lo que el comando
SELECT no es posible usarlo dentro de l.
Evita ejecutar mltiples sentencias en una sola invocacin del mtodo execSQL(). Puede
que se ejecute la primera, pero las otras no surtirn efecto.
Ahora solo queda por instancear un objeto QuotesDataSource en Main para que se cree
nuestra base de datos:
//Crear nuevo objeto QuotesDataSource

dataSource = new QuotesDataSource(this);

Al ejecutar la aplicacin se supone que la base de datos habr sido creada con xito en el
sistema de archivos de Android. Pero Cmo comprobar que as fue?la respuesta la
encontramos en el uso de las siguientes herramientas.

La Herramienta sqlite3
sqlite3 es una herramienta de administracin para nuestras bases de datos SQLite a travs
de la lnea de comandos. Normalmente puedes descargarla de la pgina oficial de SQLite,
pero tanto como la distribucin de Android y Android Studio ya la traen consigo.
Antes de ejecutarla en el dispositivo, primero usaremos la herramienta DDMS (Dalvik
Debug Monitor Server) de Android SDK, la cual permite visualizar las caractersticas del
dispositivo que se est ejecutando. En ella podemos visualizar estadsticas de rendimiento,
monitorear recursos y navegar por el sistema de archivos.
Si deseas ejecutarla solo presiona el siguiente icono en Android Studio:

Ahora dirgete a la pestaa File Explorer

Como ves, se visualizan todos los directorios que se encuentran en el dispositivo. As que
para ver si existe nuestro archivo de base de datos, iremos a la ruta de la cual hablamos al
inicio /data/data/<paquete>/databases/Quotes.db

Si todo sali bien, veremos nuestro archivo Quotes.db. Procede a gurdalo con el botn de
la parte superior derecha denominado Pull a file from the device. En la siguiente seccin
veremos algo interesante con l.

Ya que hemos comprobado que existe nuestra base de datos, iniciaremos sqlite3 dentro del
dispositivo. Sigue los siguientes pasos:
Paso #1

Inicia el terminal de Windows (cmd) o usa la pestaa Terminal de Android Studio:

Paso #2

Navega hasta el directorio platform-tools del SDK de Android. En mi caso la direccin es:
C:/Users/James/AppDataLocal/Android/android-studio/sdk/platform-tools. Recuerda que
para navegar a travs de carpetas en DOS se utiliza el comando cd.
Paso #3

Una vez hayas encontrado el directorio, digita la siguiente linea de comandos:


adb shell

Este comando conecta remotamente la consola de comandos del dispositivo Android con tu
consola local. Cuando ya ests conectado a la consola del AVD, vers en el terminal algo
como esto:
root@android:/ #

Paso #4

Inicia sqlite3 en el dispositivo con el siguiente comando:


root@android:/ # sqlite3 data/data/TUPAQUETE/databases/Quotes.db

La anterior instruccin accede a sqlite3 y al mismo tiempo le pide que abra la base de datos
expuesta en el directorio especificado. Si accedi a la base de datos vers los siguientes
mensajes:
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>

Paso #5

Usa el comando .schema de sqlite3 para ver el resumen del esquema de la base de datos
Quotes:
CREATE TABLE Quotes(_id integer primary key autoincrement,body text not
null,author text not null);
CREATE TABLE android_metadata (locale TEXT);

El Esquema muestra que nuestra tabla Quotes ha sido creada correctamente. La tabla
llamada android_metadata es parte de la metainformacin de la base de datos, por lo que
siempre la encontrars.
Otra forma de comprobar el esquema de nuestra base de datos es usar sqlite3.exe en nuestro
equipo local.
Ve a la ruta para encontrar la carpeta platform-tools del SDK de Android y ejecuta la
aplicacin.
Luego usa .open para abrir el archivo en una ruta especificada o copia y pega el archivo
Quotes.db en la carpeta:
sqlite>.open Quotes.db

Luego usa .schema y averigua su contenido.

SQLite Browser
Si deseas conocer una herramienta ms visual, entonces SQLite Browser es una opcin que
te gustara considerar. Se trata de un editor para archivos de bases de datos SQLite de
cdigo abierto y sper sencillo de usar.
Solo basta con iniciarlo en tu pc y arrastrar el archivo Quotes.db a su editor.
Inmediatamente nos mostrar el esquema en forma de tablas con interfaz grfica de usuario,
adems de permitirnos editar la estructura y ejecutar sentencias SQL dentro de ella.

Implementar CRUD En SQLite


A continuacin aprenders a Leer, Insertar, Modificar y Eliminar registros. Recuerda que
quin realiza este tipo de operaciones es la clase SQLiteDataBase.
Insertar Registros en SQLite

El mtodo cuya funcionalidad es aadir filas a nuestras tablas se llama insert(). Veamos
un ejemplo:
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,"Nueva Frase");
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,"Nuevo Autor");
//Insertando en la base de datos
database.insert(QUOTES_TABLE_NAME,null,values);

Lo primero que tenemos que hacer es crear un objeto del tipo ContentValues, el cual
permite almacenar una serie de datos(Valores) relacionados a una llave(Nombre de la
columna). Donde cada elemento es aadido con el mtodo put().
Luego invocamos a insert() a travs de la instancia de la base de datos. El primer
parmetro que recibe es el nombre de la tabla. El segundo parmetro establece que si el

objeto que contiene los valores est vaco, entonces no se debe insertar el registro en la base
de datos. Y el tercer parmetro es nuestro objeto ContentValues.
Con esta informacin ya puedes crear un mtodo de guardado en la clase
QuotesDataSource para aislar la complejidad de la actividad Main. A dicho mtodo le
llamars saveQuoteRow() y recibir el cuerpo de la frase y su autor:
public void saveQuoteRow(String body,String author){
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,body);
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,author);

//Insertando en la base de datos


database.insert(QUOTES_TABLE_NAME,null,values);

Podras usar el comando execSQL() para ejecutar una sentencia INSERT, pero como ests
recibiendo datos externos, es mejor usar insert() para evitar inyecciones SQL.
Consultar Registros en SQLite

Para obtener los registros de nuestra tabla usaremos el mtodo query().


query (String table,
String[] columns,
String selection,
String[] selectionArgs,
String groupBy,
String having,
String orderBy)

Por ejemplo, si quisiramos consultar todos los datos de la tabla Quotes usaramos el
siguiente cdigo:
Cursor c = db.query(
"Quotes", //Nombre de la tabla
null, //Lista de Columnas a consultar
null, //Columnas para la clausula WHERE
null, //Valores a comparar con las columnas del WHERE
null, //Agrupar con GROUP BY
null, //Condicin HAVING para GROUP BY
null //Clausula ORDER BY
);

Este mtodo te ayuda a aadir todas las partes posibles de las cuales se podra componer
una consulta, adems que te protege de inyecciones SQL, separando las clausulas de los
argumentos. Ahora veamos el propsito de los parmetros:

table: Nombre de la tabla a consultar

columns: Lista de nombres de las columnas que se van a consultar. Si


deseas obtener todas las columnas usas null.

selection: Es el cuerpo de la sentencia WHERE con las columnas a

condicionar. Es posible usar el placeholder ? para generalizar la


condicin.

selectionArgs[]: Es una lista de los valores que se usaran para


reemplazar las incgnitas de selection en el WHERE.

groupBy: Aqu puedes establecer cmo se vera la clausula GROUP BY, si es

que la necesitas.

having: Establece la sentencia HAVING para condicionar a groupBy.

orderBy: Reordena las filas de la consulta a travs de ORDER BY.

Debido a la simplicidad de nuestra consulta anterior, la mayora de parmetros fueron null,


ya que se consultan todas las columnas de la tabla y todos los registros. Pero si quisieras
consultar solo el cuerpo de aquellos registros donde el autor sea John D. Rockefeller
tendras que usar la siguiente clausula WHERE:
String columns[] = new String[]{ColumnQuotes.BODY_QUOTES};
String selection = ColumnQuotes.AUTHOR_QUOTES + " = ? ";//WHERE author
= ?
String selectionArgs[] = new String[]{"John D. Rockefeller"};
Cursor c = db.query(
"Quotes",
columns,
selection,
selectionArgs,
null,
null,
null
);

Se usa el parmetro selection para asignarle el nombre de la columna del cuerpo de la frase
y luego en el parmetro selectionArgs relacionas el valor a comparar.
Aprender ms sobre la clausula WHERE
Ahora, existe otro mtodo alternativo para realizar consultas llamado rawQuery(). Con l
debes crear un String que contenga todo el cdigo SQL de la consulta y lo pasamos como
parmetro.
Veamos:
database.rawQuery("select * from " + QUOTES_TABLE_NAME, null);

Si deseas crear una consulta generalizada usa el placeholder ? en la clausula WHERE. Luego
asignamos los valores a cada incgnita en el segundo parmetro:
String query = "select * from " + QUOTES_TABLE_NAME + "WHERE _id=?";
database.rawQuery(query, new String[]{"3"});
Tanto query() como rawQuery() retornan un objeto de tipo Cursor. Este objeto es un

apuntador al conjunto de valores obtenidos de la consulta. Al inicio el cursor apunta a una


direccin previa a la primera fila. La idea es leer cada fila moviendo el cursor a la fila
siguiente y as sucesivamente.
Emplea el mtodo booleano moveToNext() para recorrer el cursor. Su cometido es apuntar
al siguiente elemento del cursor, el cual retorna en true si fue posible o false si ya no existen
ms elementos.
Este concepto es similar a cuando vimos cursores en SQL Server o en MySQL. Donde
recorramos cada elemento con un bucle while hasta que ya no existieran ms elementos
que referenciar.
Veamos:
while(c.moveToNext()){
String body = c.getString(ColomunQuotes.BODY_QUOTES);
//Acciones con el valor obtenido
}

Como ves, usamos mtodos get para obtener el valor de cada columna a travs del
nombre o clave. Por ejemplo, al obtener el cuerpo de la frase usamos getString() debido
a que su tipo en la tabla es text. Si fueses a obtener el cdigo, entonces usas getInt().
Puedes aprovechar este nuevo concepto e implementar un nuevo mtodo en la clase
QuotesDataSource llamado getAllQuotes(). Su objetivo es retornar en un cursor todas
las filas de la tabla Quotes, lo que asla la complejidad de la operacin sobre la base de
datos de la actividad Main:
public Cursor getAllQuotes(){
//Seleccionamos todas las filas de la tabla Quotes
return database.rawQuery(
"select * from " + QUOTES_TABLE_NAME, null);
}
Al igual que saveQuoteRow() y getAllQuotes(), puedes crear otros mtodos

para borrar,

modificar o realiza consultas especificas. Tu objetivo siempre debe ser eliminar


dependencias entre la actividad y el manejo de la base de datos.
Borrar Registros en SQLite

Eliminar registros es muy sencillo, solo tenemos que usar el mtodo delete(). Recibe
como parmetros el nombre de la tabla, el estilo de la seleccin de la clausula WHERE y los
valores de comparacin para determinar que filas borrar.

Por ejemplo, eliminar la frase que tenga el cdigo 3:


String selection = ColumnQuotes.BODY_QUOTES + " = ?";
String[] selectionArgs = { "3" };
db.delete("Quotes", selection, selectionArgs);

Actualizar Registros en SQLite

En este caso usaremos el mtodo update(). Es exactamente el mismo estilo de uso que los
anteriores mtodos. Especificaremos el nombre de la tabla, los valores nuevos que vamos a
usar y luego pondremos las cadenas de la instruccin where y sus argumentos
comparativos:
//Nuestro contenedor de valores
ContentValues values = new ContentValues();
//Seteando body y author
values.put(QuotesDataSource.ColumnQuotes.BODY_QUOTES,"Nueva Frase");
values.put(QuotesDataSource.ColumnQuotes.AUTHOR_QUOTES,"Nuevo Autor");
//Clausula WHERE
String selection = ColumnQuotes.BODY_QUOTES + " = ?";
String[] selectionArgs = { "3" };
//Actualizando
database.update(QUOTES_TABLE_NAME, values, selection, selectionArgs);

La Clase CursorAdapter
Existe un adaptador especial para el manejo de bases de datos llamado CursorAdapter.
Esta clase permite poblar una lista a travs de un cursor. Es decir, el origen de datos no ser
una lista ni un arreglo, si no un cursor.
es una clase abstracta de la cual se ha de crear tu adaptador personalizado.
Con ArrayAdapter tenamos que sobrescribir el mtodo getView() para inflar nuestras
filas con los datos de la lista. Pero no es el caso con CursorAdapter. Esta vez debemos
sobrescribir dos mtodos aislados llamados bindView() y newView().
CursorAdapter

es el encargado de poblar la lista con los datos del cursor y newView() es


quien infla cada view de la lista. Al implementar ambos mtodos no debemos preocuparnos
por iterar el curso, esto es manejado internamente.
bindView()

As que escribamos nuestra nueva clase QuotesAdapter. En bindView() simplemente


debemos obtener los valores de las columnas y setearlos en los text views del layout. Y en
newView() accedemos a la instancia del LayoutInflater a travs del parent y luego
invocamos inflate() para inflar nuestra fila.
Observemos:
public class QuotesAdapter extends CursorAdapter {

public QuotesAdapter (Context context, Cursor cursor) {


super(context, cursor);
}
public void bindView(View view, Context context, Cursor cursor) {
TextView body = (TextView)view.findViewById(R.id.bodyText);
//Setear el texto del a columna en la posicin 0 del cursor
body.setText(cursor.getString(cursor.getColumnIndex(0)));
TextView author = (TextView)view.findViewById(R.id.authorText);
author.setText(cursor.getString(cursor.getColumnIndex(1)));
}
public View newView(Context context, Cursor cursor, ViewGroup parent)
{

LayoutInflater inflater = LayoutInflater.from(parent.getContext());


View view = inflater.inflate(R.layout.list_item, null, false);
return view;
}

Ahora solo debemos cargar nuestra actividad principal e instancear nuestro adaptador con
un cursor que apunte a todos los registros de nuestra tabla Quotes.
adapter = new QuotesAdapter(this, sourceData.getAllQuotes());
setAdapter(adapter);
Por razones de compatibilidad en los procesos de manipulacin de datos CursorAdapter

exige que uses en todas tus tablas una llave fornea cuya etiqueta sea _id, si no lo haces
se generar un error en tiempo de ejecucin.

La Clase SimpleCursorAdapter
Si el diseo de las filas de tu lista es sencillo, entonces la clase SimpleCursorAdapter
podra ahorrarte tiempo de desarrollo. Esta clase es una extensin de CursorAdapter que
posee una implementacin completa para los desarrolladores. Con ella no tenemos que
sobrescribir mtodos ni tampoco crear un archivo de diseo, ya que permite usar layouts
del sistema.
Nuestra aplicacin Quotilius tiene elementos sencillos, por qu slo usamos dos text views
para mostrar el cuerpo de la frase y el autor. Por esta razn podemos usar el layout del
sistema two_line_list_item. Fjate como sera la creacin de un nuevo adaptador:
//Iniciando el nuevo Adaptador
adapter = new SimpleCursorAdapter(
this,//Context context
android.R.layout.two_line_list_item,//int layout
dataSource.getAllQuotes(),//Cursor c
new String[]
{ColumnQuotes.BODY_QUOTES,ColumnQuotes.AUTHOR_QUOTES},//String[] from
new int[]{android.R.id.text1, android.R.id.text2},//int[] to
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER//int flags
);

setListAdapter(adapter);

Comprendamos un poco los parmetros:

context: Es el contexto donde se encuentra la lista, en este caso es la

misma actividad.

layout: Es el layour que usaremos para inflar los elementos de cada fila.

En nuestro caso usamos el prefabricado por Android para los elementos


con dos text views

c: Es el cursor que representa el origen de datos para el adaptador.

Asignamos el cursor hacia todos los registros de la tabla Quotes.

from: Es un arreglo de Strings que contiene el nombre de las columnas a

consultar. Usamos los nombres de las columnas que contiene


ColumnQuotes.

to: Es un arreglo de enteros con las referencias directas de los text views

en el layout. Deben tener el mismo orden que las columnas. Los


TextViews dentro de two_line_list_item.xml se llaman text1 y text2
respectivamente.

flags: Es un bandera para establecer el comportamiento del adaptador.


FLAG_REGISTER_CONTENT_OBSERVER registra un observador adherido al

cursor para saber cundo cambio su informacin y as refrescar la lista.

Finalmente completaremos el mtodo onActivityResult() para guardar el nuevo registro.


Si la actividad Form retorna los datos de forma correcta, entonces lo primero que debemos
realizar es obtener los extras que trae el Intent de regreso, luego insertamos el nuevo
registro con el mtodo saveQuoteRow() y por ltimo usamos el mtodo changeCursor()
para actualizar el cursor y as refrescar los elementos de la lista:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == ADD_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
//Insertando el registro con los datos del formulario
String body = data.getStringExtra("body");
String author = data.getStringExtra("author");
dataSource.saveQuoteRow(body,author);
//Refrescando la lista
adapter.changeCursor(dataSource.getAllQuotes());
}

}
}

Conclusin
Hasta aqu ya tienes claro cmo usar una base de datos SQLite sencilla en Android.
Viste como usar una clase tipo contrato para estandarizar la estructura de las tablas y
columnas.
Adems aprendiste a usar sqlite3 y SQLite Browser para editar y visualizar tu modelo de
datos.
Incluso viste adaptadores especializados para alimentar listas desde cursores.
Ahora solo queda seguir aumentando el nivel de implementacin. Es necesario que
aprendas a cubrir una base de datos con mltiples tablas y a proteger los datos con un
ContentProvider.
Tambin es recomendado emplear las clases AsyncTask o IntentService para aislar las
operaciones sobre la base de datos a un segundo plano. Operar la base de datos
directamente sobre el hilo de UI puede producir problemas de rendimiento y visualizacin.
Ah, y si vas a usar el nuevo RecyclerView con un Cursor en la creacin de una lista
alimentada desde SQLite, observa el siguiente artculo: RecyclerView Con Cursor En
Android.
Artculos Relacionados

Base De Datos SQLite En Android Con Mltiples Tablas

Crear Triggers en MySQL

AsyncTask: Tareas Asncronas en Android


Acerca Del Autor
James Revelo

JL

Hola James!
He creado nuevas columnas en mi base de datos y quiero que se actualice
automaticamente de la antigua version a la nueva. Como puedo ejecutar el mtodo
onUpgrade para que se creen esas nuevas columnas en esa misma tabla y se inserten
los valores correspondientes? Me da diferentes errores, que si la tabla ya existe y no
puede volverse a crear o que si hay ms valores que tablas en INSERT. Gracias!
El cdigo:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.delete(DataSource, null, null);
db.execSQL(DataBase.INSERT_SCRIPT);
}
o

James Revelo Urrea

Hola JL, ests usando el comando UPDATE, recuerda que con este se
aaden nuevas columnas a las tablas ya existentes. No uses delete si deseas
conservar los datos.

JL

Hola James.
He editado el comentario porque ya he solucionado el problema,
pero he encontrado otro relacionado.
Cuando ejecuto mi app o tu cdigo de ejemplo en versiones de Sqlite
menores a la 3.7.11 (Android 4.0 o menos) me salta el siguiente
error:
android.database.sqlite.SQLiteException: near ,: syntax error:
insert into DATABASE
values(null,a,a,a,a,a,a,b,c,
He estado buscando en Internet y creo que he encontrado la solucin,
pero no se como aplicarla. Es la siguiente:
http://stackoverflow.com/questions/15966165/sqlite-with-ios-5-issue
A tu cdigo como se le aplicaria?
Gracias.

James Revelo Urrea

Debes insertar cada registro por separado, ya que en esas


versiones de sqlite no es posible realizarlo con una sola
sentencia.

D.Castt

Excelente tutorial, felicidades, para los que venimos comenzando.


El problema con los que estamos intentando algo diferente, y pues, usamos de
referencia el manual, es que no sabemos algunas cosas, en donde las pones, por lo
que seria buenisimo ser capaz de descargar el source :) pero, muy bien y detallado.
o

James Revelo Urrea

Gracias compaero. El cdigo puedes descargarlo al inicio del artculo desde


una cajita donde compartes en redes sociales y se desbloquea un botn.
Espero actualizar este artculo para incluir pasos mas detallados y no dejar
lugar a dudas.

Saludos!

Miguel Rivera

Muy buen tutorial, soy nuevo en android, y queria consultar, como se maneja la
base de datos cuando quieres que la aplicacin se ejecute de manera local solo en el
dipositivo sin conexion a internet, y donde podria encontrar algun tutorial, para
exportar esa data guardada en la base de datos hacia un archivo excel.
saludos.

Mario German Agudelo

Hola estoy interesado en llamar desde mi base de datos la informacin para el


google map, ya que son varios puntos de localizacin fijos, tienes alguna idea de
cmo se podra hacer. Agradezco tu ayuda.

Luis Pea

Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.

Luis Pea

Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.

Luis Pea

Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieses algn consejo o algn link.
Estoy pensando tambin en apuntarme a uno de vuestros cursos.

victor

Hola James!
Como siempre una pasada el tutorial, pero quera comentarte una cosa que estoy
viendo bastante en android que es que no se trabaja casi con clases de definicin o
como se llamen(disculpa pero no he estudiado informtica y no se muy bien como
nombrarlo), es decir, cuando trabajo por ejemplo en php, en MVC, en el modelo me
traigo la informacin que necesito de BD, y digamos que informo al objeto de una
clase, como puede ser la clase Usuario con las variables fecha_de_nacimiento,
corre, etc, y lo guardo en un array de Usuarios para trabajar con dicha clase. Claro
aqu me pregunto porque utilizas los datos directamente y no pueblas por ejemplo la
clase Quotes(abra que crearla primero con sus getters i setters), con los parametros
id, autor y frase, y los almacenas en un array de Quotess? No s si en Android no se
trabaja igual, o no lo s.
Tambin ya que te hablo de php, como segunda pregunta, quera preguntar si el
tema del login en android funciona de forma similar a php, es decir, cuando haces
login en android, existe una SESSION o algo similar, para diferencias por ejemplo
algunos mens o caractersticas de la app entre usuarios que no estas registrados y
usuarios que si lo estn? Es decir, que una opcin o botn sea solo visible para
usuarios registrados(logueados). Porque lo que he visto que realizas en el tutorial de
sincronizacin con php, requiere como una conexin constante, y la idea de la app
que estoy haciendo (un tutorial offline) tengan partes para usuarios registrados y
otras ocultas para usuarios no registrados. Y la idea que tengo es traerme datos a la
BD local del movil y hacer el login en local(que no se s es muy seguro) o tambin
como otra posible idea, es que el primer login sea con Internet, y luego quede
marcada la app con alguna SESSION o algo como en php, que ese usuario siga
logueado sin necesidad de comprobarlo nuevamente con el servidor. Claro, la idea
es que si esa persona se da de baja, deje de tener acceso a los apartados de solo
usuarios registrados(cosa que se comprobara cada X tiempo si tiene internet). Pero

bueno, no tiene porque ser est la lgica, pero supongo que ms o menos ves por
donde quiero llegar.
Disculpa por el carro que te he soltado, pero as aclaro un poco mis ideas jejej, pero
ms que nada no s si son ideas de funcionamiento muy disparatadas, y me gustara
escucharte a ti, para tener una referencia de un experto en android y no estar
buscando soluciones en google que me llevan a golpearme contra el muro.
Muchas gracias por todo James y por tu tiempo, espero no tener que molestarte
mucho ms.
Un saludo!
Vctor.
o

victor

Respondindome a la primera para lo que quiero hacer trabajara


directamente con el Cursor de la base de datos al realizar la consulta y luego
hara un bucle for, para alimentar la clase Quotes, e ir guardndolo en un
arrray de Quotes. Y as tener una array con toda la informacin que necesite
y luego poder trabajar con ella. Y luego con un adaptador por ejemplo de
ArrayList a lo que necesite Que opinas? Y estos procesos de por ejemplo
el bucle for, no s si son muy rpidos, pero supongo que todas estas
operaciones no es conveniente que se realicen en el hilo principal, y hacer un
servicio para todas estas costias no? o se pueden ejecutar en el hilo
principal?
Muchas gracias!

Yeni Paola Trujillo Lambert

Buena tardes primero quiero decir que es un buen tutorial muy completo, quisiera
hacerle una pregunta si yo quiero guardar los datos que obtengo del acelerometro
del celular como podria hacerlo.
Estare atenta a cualquier dato que puedas regalarme gracias

Leo

Pocas veces uno encuentra en la red tutoriales tan completos y claros. Mis
felicitaciones. Soy un programador que se inicia en android, y mis primeros pasos
sern desde aqu. Le reitero mis felicitaciones.
o

James Revelo Urrea

Que bien Leo, me alegra que sea de utilidad para ti. Si quieres ahondar ms
sobre sqlite, te dejo este link para crear una db con varias tablas:
http://www.hermosaprogramacion.com/2016/01/base-de-datos-sqlite-enandroid-con-multiples-tablas/
Saludos!

Fernando Etchepare Scatena

Muchas gracias por la nota. Me ha sido de gran utilidad! :)


o

James Revelo Urrea

Gracias Fernando, excelente que te haya servido, saludos!

jesus

Hola, tengo una base de datos sqlite y la muestro en un listview mediante un


adaptador que extiende de cursor adapter (empleando los metodos newView y
bindView) pero sorprendentemente no se interactua con las filas del listview , es
decir , no se puede hacer click sobre ellas ni longclick.
Gracias por los posibles consejos, saludos

Jhury

hola.. quisiera saber como cargar una base de datos ya existente creada en sqlite, a
android studio para poder actualizar y agregar nuevos registros a las diferentes
tablas de mi base de datos.

Martin (Argentina)

nada mas felicitarlo por hacer tan buenos tutoriales, y por la abundancia de detalles,
algo que nunca debera de faltar en este mbito, xitos!
o

James Revelo Urrea

Gracias compaero! :)

Cristian

hola que tal , el codigo de esta app como puedo abrirlo en ANDROID STUDO?

erick

Disculpa tengo mi proyecto en android y el emulador si funciona bien pero cuando


lo instalo al telefono no funciona el login ni las conecciones a la base de datos que
solucion tendria??
o

James Revelo Urrea

Hola erick. puedes ver algunos resultados del error en tu logcat? o


simplemente la app se detiene?

erick

no se detiene simplemente no se conecta con mi base de datos(Es lo


que imagino) enmconces tendria que adjuntar la basede dato al
proyecto tambien??

James Revelo Urrea

La app que intentas aplicar es la que descargaste desde este


articulo o es una tuya?

erick

no la cree yo !

James Revelo Urrea

Mmm compaero pues debes revisar la app, tal vez


hay un error o has cambiado la ruta de la base de
datos a un lugar donde tu cel no te da permisos de
acceso

erick

no creo, entonces deveria adjuntar la base de datos a


la SD y jlar los datos ahi para que me funcione en
celular o tableta??

James Revelo Urrea

No propiamente. Se supone que la ruta por defecto


funciona bien en el almacenamiento interno. Si
pruebas tu app en varias versiones de emuladores,
funciona en todos?

Pablo

Una consulta rpida:


Tengo una base de datos con MySQL en la cual tengo una tabla producto que est
relacionada con la tabla Imagen de tal manera que un Producto puede tener 1 o
ms imgenes siendo una de ellas la imagen Principal (indicado con un valor
boolean).
Para adaptarlo a SQLite y utilizar Sync Adapters es recomendable mantener ambas
tablas en la base de datos local de mi aplicacin y mantener la relacin o para evitar
tratar con ms tablas puedo migrar los atributos de la tabla Imagen a la otra tabla
teniendo:
o

James Revelo Urrea

Hola Pablo. Manten las dos tablas, SQLite es relacional, de modo que no
tenemos porque restringirnos de esas cualidades.
Lo nico adicional es que debes aadir la nueva tabla como una clase
esttica al contrato o script de la base de datos en tu app.
SQLite soporta la restriccin FOREIGN KEY, pero tiene limitaciones en su
uso. Sin embargo sin esta clausula tambin es posible manejar las relaciones
con solo lgica de programacin.
Creo que voy a hacer un artculo sobre esta cuestin.

Pablo

Muchas gracias. Le echar un ojo a dicho artculo cuando est listo

Alejandro Luna Espinosa

Primero que nada te agradezco por tu tiempo y te felicit por tu pgina, tengo una
consulta, tengo ya desarrollada una aplicacin que usa base de datos, pero me
gustara agregarle que se sincronicen los datos de esta, por si se pierde el dispositivo
o es robado poder acceder los datos nuevamente, hay algn otra alternativa al de
MySQL?
o

James Revelo Urrea

Hola Alejandro.
Cuando hablas otra alternativa a Mysql te refieres a otro gestor de bases de
datos o a otro mtodo que no tenga que ver con bases de datos?.

Podras realizar un backup en la cuenta de google drive de cada usuario para


que los datos queden guardados. Luego el usuario podra cargar de nuevo
ese backup en la app para no perder su informacin.

Alejandro Luna Espinosa

Hola James.
Lo siento no me di a explicar bien, me refera a la manera de poder
respaldar esos datos en mi base de datos sqlite en android, me
interesa eso que comentas del backup en google drive de los datos y
con la cuenta de google puedas recuperarlos nuevamente. Tendrs
fuentes o informacin que me puedas proporcionar para implementar
eso? Te agradezco mucho, mi aplicacin es una sencilla app de de
hacer notas pero me gustara implementar poder recuperar esa
informacin. Saludos
Dejo el Link
https://www.dropbox.com/s/f9xcxf4hmfrs0sm/Notas.apk?
dl=0&oref=e

James Revelo Urrea

En el momento no tengo tutoriales sobre este tema, pero


puedes ver enlaces relacionados como esta gua para hacerlo
localmente:
http://developer.android.com/intl/es/guide/topics/data/backup.
html
O la api de drive:
https://developers.google.com/drive/android/appfolder

Aniel Cisneros

Hola buen da James!


Por aqu molestndote nuevamente :)
Estoy construyendo una Base de datos con cantidades de palabras (tipo diccionario
de palabras), sonidos e imgenes. Mi duda es la siguiente, deseo alojar esa base de
datos en internet para que al ejecutar la aplicacin se pueda obtener esa base de
datos para usarse dentro de ella (y no crearse desde cero dentro de la app), ya que no
deseo que el usuario la actualice, solo yo podr actualizarla o corregirla y as subirla
a internet para que se pueda usar desde la app (obviamente despus de hacer una

comparacin de la nueva versin con la que contiene la app al iniciarse). Es


posible hacer esto? Tienes algn tutorial?
Saludos!
o

James Revelo Urrea

Hola Aniel.
Hablas de sincronizar los datos?
Claro, aqu hay uno con Mysql y Sqlite:
http://www.hermosaprogramacion.com/2015/07/como-sincronizar-sqlitecon-mysql-en-android/

Diego A. Juchani S.

Hola Tengo dudas cuando hago consultas cuando no hay registros en la tabla me
sale un error y se cierra la app. como puedo controlar o saber si existe la tabla y la
base de datos. por favor le pido que me ayude.
o

James Revelo Urrea

Hola Diego.
Me imagino que sucede cuando intentas recorrer el Cursor.
Asegrate de que el cursor no sea null con una sentencia IF antes de obtener
sus datos.
o

san

bueno creo que aveces obtienes un cursor no nulo pero con 0 entradas como
resultado.. podrias asegurarte haciendo algo asi: if (cursor != null) { if
(cursor.length > 0) { // se obtuvo un resultado con mas de una fila } // se
obtuvo un cursor con 0 filas entrantes }

San

Buenas soy algo nuevo en esto, MUCHAS GRACIAS por el tutorial muy bueno.
Estoy liado con una app android y ya he conseguido trabajar localmente con la base
de datos SQLITE. Pero mi pregunta es Solo sirve para trabajar localmente cierto?
como se sincroniza con los demas dispositivos que tengan tambin su propia local?
. supongo que habria que conectar la base de datos SQLite local con alguna base
de datos de algun servidor externo no? algun consejo?

Simplemente pretendo es que alguien inserte algo nuevo en la base de datos, y


puedan verlo automaticamente todos los demas desde su dispositivo xD.
o

James Revelo

Hola San.
Si, a mi parecer la solucin mas viable sera usar un servidor. La idea sera
tener una base de datos remota para que haya una sincronizacin entre los
dispositivos.
Pronto publicar un tutorial sobre sicronizacin, creo que puede darte
algunas ideas.

san

De acuerdo gracias! estar atento, je.

Luis Mario

tengo un problema al comunicarme con una base de datos existente

Juan Carlos

Hola, muy bueno el tutorial. Tengo una pregunta, Cada vez que la aplicacin se
ejecuta se crea una nueva base de datos, o android advierte que ya existe la base de
datos con la misma versin y no la crea?.
o

James Revelo

Hola Juan.
Si solo se crea una vez. Si se desea cambiar para actualizarla debes usar
onUpgrade() para gestionar un cambio de versin.

memo

es bueno solo flataria una descricion de cada codigo sobre el manejo de la creacion
de tablas, comapos y la base de datos.. :) muy buena :) :33

Denisb

Esta bueno el tutorial, pero le hace falta un poco mas, en la clase QuotesAdapter
muestra error al setear los EditText y entre otros errores, e igual al descargar el
cdigo no viene la clase QuotesAdapter.

pero gracias por el tutorial.


Saludos.
o

James Revelo

Gracias por tus apreciaciones Denisb. Voy a revisar los archivos para montar
el proyecto completo y mejorado.
Saludos amigo :D

LAURA CRISTINA BECERRA GONZALEZ

no me es posible descargar el cdigo

http://www.hermosaprogramacion.com/android/

Conecta con SQLite en apps android[Android Studio]


Para el entendimiento de este procedimiento en android vamos a crear una
pequea y sencilla app que ser como una pequea agenda, la cual va a estar
conectada con una Base de Datos en SQLite y almacenar los siguientes datos:

id: INTEGER
Nombre: Text
Apellido: Text
Telefono: Text // Tambin puede ser de tipo INTEGER
E-Mail: Text
El objetivo de esta app ser conectarse a la Base de Datos creada en SQLite y
realizar las siguientes operaciones con los datos:
1.- Insertar Datos
2.- Consulta y Muestra de Datos
3.- Eliminar Uno o Todos los Datos
Para no hacer tan largo el post por el momento slo vamos a conectar con la
base de datos e insertar los datos.
En el primer ActivityMain creamos los botones para realizar la operaciones en
otros Activities de la sigueinte manera:

Despus creamos el Activity para Insertar los Datos, para crear otro activity en
Android Studio nos vamos al archivo AndroidManifest.xml, damos click derecho
y en new- acitivity. En la siguiente ventana Blank, despus siguiente, damos
nombre y finalizar.

Ya esta creado el segundo activity, el cual debe tener 4 text large, 4 editText y
2 botones de la siguiente manera:

Ahora hacemos la funcin para pasar al segundo activity, es decir pasar del
Principal al segundo Activity, nos vamos al MainActivity.java que es el que hace
referencia al activity_main.xml:
public void pasaSegundo(View view) {
Intent i = new Intent(this, MainActivity2.class ); //MainActivity
2 es el nombre del .java
//Del segundo Activity
startActivity(i);
}

cdigo completo:
package com.bd.bdapp.app;
import
import
import
import
import
import
import
import
import

android.app.AlertDialog;
android.content.DialogInterface;
android.content.Intent;
android.support.v7.app.ActionBarActivity;
android.os.Bundle;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.widget.EditText;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is p
resent.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will

// automatically handle clicks on the Home/Up button, so long


// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void pasaSegundo(View view) {
Intent i = new Intent(this, MainActivity2.class );
startActivity(i);
}
}

Para Asociarla al botn nos vamos al xml y en la vista diseo seleccionamos el


botn y del lado derecho salen las propiedades y buscamos donde dice onClick
y ponemos el nombre del mtodo que hicimos en este caso debe ser
pasaSegundo y damos enter.

Ahora vamos a programar la clase que va a crear la BD, que va a gestionar la


versiones de la BD y nos dar acceso a sta. Para esto en android se hace uso

de la clase SQLiteOpenHelper, por lo cual crearemos una clase que va a


heredar de SQLiteOpenHelper. Al hacer esto automticamente nos generar el
constructor y los siguientes mtodos: onCreate(SQLiteDatabase db) que
sirve para crear la tablas una vez que crea la BD y otro es
onUpgrade(SQLiteDatabase db, int i, int i2) que nos ayudar a gestionar
la versiones de la BD. Queda de la siguiente forma:
package com.bd.bdapp.app;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by root on 19/04/14.
*/
public class BD extends SQLiteOpenHelper {
//Query para crear las tablas en la bd
String query="CREATE TABLE personas (id INTEGER PRIMARY KEY AUTOINCRE
MENT, Nombre TEXT, Apellido TEXT, Telefono TEXT, Email TEXT)";
//Constructor de la clase
public BD(Context context, String name, SQLiteDatabase.CursorFactory
factory, int version) {
super(context, name, factory, version);
}

@Override
public void onCreate(SQLiteDatabase db) {
//Ejecuta query para crear la tabla
db.execSQL(query);
}
@Override
public void onUpgrade(SQLiteDatabase db, int i, int i2) {
db.execSQL("DROP TABLE IF EXISTS personas");
//Se crea la nueva versin de la tabla
db.execSQL(query);
}
}

Ahora crearemos otra clase para acceder a la base de datos y manejar los
datos de sta, vamos a empezar con el mtodo de para inserta, le vamos a
llamar ConexionBD:

package com.bd.bdapp.app;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import java.util.ArrayList;
import java.util.List;
/**
* Created by root on 19/04/14.
*/
public class ConexionBD {
private SQLiteDatabase db;
private Context nContext;
private BD objBD;

//Constructor de la Clase
//Recibe como parmetro una variable de Tipo contexto
// Esto debido a que Para acceder o crear la BD lo pide la Clase SQLi
teOpenHelper
public ConexionBD(Context c){
nContext=c;
}
public void abrirConexion(){
objBD =new BD(nContext,"BDAgenda",null,1 );
db=objBD.getWritableDatabase();
}
public void cerrarConexion(){
db.close();
}
public boolean insertar(String nombre, String apellido,String telefon
o,String email){
boolean resultado=false;
try{
String query="INSERT INTO personas(Nombre, Apellido, Telefono
, Email) VALUES('"+nombre+"','"+apellido+"','"+
telefono+"','"+email+"')";
db.execSQL(query);
resultado=true;
return resultado;
}
catch (Exception e){

resultado=false;
return resultado;
}
}
}

Ahora vamos al .java del Segundo activity, en nuestro caso es


MainActivity2.java y hacemos los eventos de los botones:
primero el del botn limpiar
//declaramos los editText y en el Oncreate se inicializan
private EditText nombre,apellido,telefono,email;
//mtodo para limpiar los editText
public void limpiar(View view){
nombre.setText("");
apellido.setText("");
telefono.setText("");
email.setText("");
}

Despus creamos el mtodo para insertar


public void agregar(View view){
//Declaramos variables
String nombre,apellido,telefono,email;
//Obtenemos Texto de los TextEdit
nombre=this.nombre.getText().toString();
apellido=this.apellido.getText().toString();
telefono=this.telefono.getText().toString();
email=this.email.getText().toString();

Creamos el Objeto para acceder a la BD


ConexionBD ObjCnx = new ConexionBD(this);
ObjCnx.abrirConexion(); //Abrimos Conexin
//Ejecuta el mtodo para Insertar Datos
if(ObjCnx.insertar(nombre,apellido,telefono,email)==true){
String texto ="Elemento Agregado Corectamente";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);
toast.show();
}
else{
String texto ="Error al Agregar Elemento";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);

toast.show();
}
Cerramos Conexin
ObjCnx.cerrarConexion();
}

Cdigo comlpeto del ActivityMain2.java:


package com.bd.bdapp.app;
import
import
import
import
import
import
import
import
import
import
import
import
import

android.app.AlertDialog;
android.app.Dialog;
android.content.DialogInterface;
android.database.Cursor;
android.database.sqlite.SQLiteDatabase;
android.support.v7.app.ActionBarActivity;
android.os.Bundle;
android.view.Menu;
android.view.MenuItem;
android.view.View;
android.widget.EditText;
android.widget.TextView;
android.widget.Toast;

import java.util.List;
public class MainActivity2 extends ActionBarActivity {
private EditText nombre,apellido,telefono,email;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
nombre=(EditText)findViewById(R.id.editText);
apellido=(EditText)findViewById(R.id.editText2);
telefono=(EditText)findViewById(R.id.editText3);
email=(EditText)findViewById(R.id.editText4);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is p
resent.
getMenuInflater().inflate(R.menu.main_activity2, menu);

return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void limpiar(View view){
nombre.setText("");
apellido.setText("");
telefono.setText("");
email.setText("");
}
public void agregar(View view){
String nombre,apellido,telefono,email;
nombre=this.nombre.getText().toString();
apellido=this.apellido.getText().toString();
telefono=this.telefono.getText().toString();
email=this.email.getText().toString();
ConexionBD ObjCnx = new ConexionBD(this);
ObjCnx.abrirConexion();
if(ObjCnx.insertar(nombre,apellido,telefono,email)==true){
String texto ="Elemento Agregado Corectamente";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);
toast.show();
}
else{
String texto ="Error al Agregar Elemento";
Toast toast = Toast.makeText(this, texto, Toast.LENGTH_LONG);
toast.show();
}
ObjCnx.cerrarConexion();
}
}

Ya slo nos resta asociar los mtodos con cada botn.


Capturas de la APP

SQLite: ejemplo de acceso a base de datos

Base de Datos, Nivel Medio-Avanzado SQLite: ejemplo de acceso

06/06/2014

Base de Datos, Nivel Medio-Avanzado

Post Series: SQLite: herramientas y casos prcticos de gestin de bbdd

1.SQLite: introduccin y herramientas de administracin

2.SQLite: ejemplo de acceso a base de datos

3.Videotutorial: gestin base de datos en Android con SQLite Manager


(plugin Firefox)

4.Acceso a base de datos en Android por DDMS

Proyecto realizado con API SQLite


Para el siguiente ejercicio que vamos a desarrollar, hemos utilizado la API SQLite para
crear una Base de Datos llamada Ferreteria, en la que se va a crear una tabla llamada
Ventas, que almacenarn una lista de artculos que se irn gestionando desde la pantalla
principal de la aplicacin Android.
Puedes descargarte el cdigo del proyecto completo. Te agradeceramos que a cambio, si
te es posible, nos ayudaras a difundir este tutorial en alguna de las redes sociales cuyos
iconos te aparecen a la izquierda. Gracias!
Descargar
Estructura Base de Datos

Podemos ver en la imagen de abajo, la base de datos que vamos a utilizar en el ejemplo,
con los campos de la tabla que vamos a crear:

En primer lugar crearemos un proyecto con el siguiente SDK:


[...]
<uses-sdk
android:minSdkVersion="8"

[...]

2
3

<uses-sdk

android:minSdkVersion="8"

android:targetSdkVersion="18" />

6
7

[...]

Tras crear el proyecto, se definen en nuestra Clase MainActivity los Controles necesarios
para la lgica de la aplicacin:
[...]
/ / Declaramos los controles nece
private EditText edProducto;
private EditText edCantidad;

1 [...]
2 //Declaramos los controles necesarios para la lgica de la aplicacin
3 private EditText edProducto;
4 private EditText edCantidad;
5 private EditText edId;
6 private Spinner spnSeccion;
7
8 //Declaramos la clase encargada de crear y actualizar la Base de Datos
9 MiBaseDatos basedatos;
1 [...]
0
1
[...]
1
1
2 //Enlazamos los controles definidos con sus recursos a nivel de layout
1 edProducto = (EditText)findViewById(R.id.edProducto);
3
edCantidad = (EditText)findViewById(R.id.edCantidad);
1
4 spnSeccion = (Spinner)findViewById(R.id.spinnerSeccion);
1 edId = (EditText)findViewById(R.id.edIdentificador);
5
1 //Creamos un Array de String con las secciones de una ferretera
6
String[] secciones =
1 {"Electricidad","Fontanera","Cerrajera","Jardinera","Tornillera","Vestimenta
7 "};
1 spnSeccion.setAdapter(new ArrayAdapter<String>(this,
8 android.R.layout.simple_spinner_item, secciones));
1

9
2
0
2
1
2
[...]
2
2
3
2
4

Adems se han definido cuatro botones encargados de lanzar los eventos On Click para las
operaciones CRUD (Create-Read-Update-Delete):
Ruta:StockFerreteria/com.academiaandroid.stockferreteria/MainActivity.java
En la imagen de abajo vemos la interfaz de nuestra aplicacin, con los botones para
realizar las operaciones CRUD:

Guardar un Registro:

[...]
/ / Evento On Click para guardar
public void guardarProducto(V

1 [...]
2 //Evento On Click para guardar un producto en la tabla Ventas
3

public void guardarProducto(View view)

5 //Se inicializa la clase.


6 basedatos = new MiBaseDatos(this);
7
8 //Clase que permite llamar a los mtodos para crear, eliminar, leer y
actualizar registros. Se establecen permisos de escritura.
9
SQLiteDatabase sqlite = basedatos.getWritableDatabase();
1
0 ContentValues content = new ContentValues();
1 [...]
1
1
[...]
2
1
3 //Se aaden los valores introducidos de cada campo mediante
clave(columna)/valor(valor introducido en el campo de texto)
1
4 content.put(Estructura.COLUMN_NAME_PRODUCTO,producto);
1 content.put(Estructura.COLUMN_NAME_CANTIDAD, cantidad);
5
content.put(Estructura.COLUMN_NAME_SECCION, seccion);
1
6 sqlite.insert(Estructura.TABLE_NAME, null, content);
1 [...]
7
1 [...]
8
//Se cierra la conexin abierta a la Base de Datos
1
9 sqlite.close();
2

0
2
1
2
2
2
3
2
4
2
5

Buscar un Registro por Producto:


[...]
/ / Evento On Click para buscar u
public void buscarProducto(V

1 [...]
2
3 //Evento On Click para buscar un producto en la tabla Ventas por nombre
4

public void buscarProducto(View view)

6
7
8
9
1
0
1
1
1
2
1

basedatos = new MiBaseDatos(this);


//Se establecen permisos de lectura
SQLiteDatabase sqlite = basedatos.getReadableDatabase();
//Columnas que devolver la consulta.
String[] columnas = {
Estructura._ID,
Estructura.COLUMN_NAME_PRODUCTO,
Estructura.COLUMN_NAME_CANTIDAD,
Estructura.COLUMN_NAME_SECCION

3
1
4
1
5

};

//Clusula WHERE para buscar por producto


String producto = Estructura.COLUMN_NAME_PRODUCTO + " LIKE '" +
edProducto.getText().toString() + "'";

1
6
//Orden de los resultados devueltos por Producto, de forma Descendente
1
alfabticamente
7
String ordenSalida = Estructura.COLUMN_NAME_PRODUCTO + "DESC";
1
8
1 [...]
9
2
0 [...]
2
1 //Ejecuta la sentencia devolviendo los resultados de los parmetros pasados
2 de tabla, columnas, producto y orden de los resultados obtenidos.
2

Cursor cursor = sqlite.query(Estructura.TABLE_NAME, columnas,


2 producto,null, null, null, ordenSalida);
3
2 [...]
4
2
5 [...]
2 //Se cierra la conexin abierta a la Base de Datos
6
sqlite.close();
2
7
[...]
2
8
2
9
3
0
3

1
3
2
3
3
3
4
3
5
3
6
3
7

Borrar Registro por nombre de Producto:


[...]
/ / Evento On Click para eliminar
public void borrarProducto(Vie

1 [...]
2 //Evento On Click para eliminar un producto de la tabla Ventas por el nombre
3

public void borrarProducto(View view)

5 //Se inicializa la clase.


6

basedatos = new MiBaseDatos(this);

7
8

//Se establecen permisos de escritura

SQLiteDatabase sqlite = basedatos.getWritableDatabase();

1
0

[...]

1
1
1
2

[...]
//Se especifica en la clusula WHERE el campo Producto y el producto

1
3
1
4
1
5
1
6
1
7
1 introducido en el campo de texto a eliminar
8
String consulta = Estructura.COLUMN_NAME_PRODUCTO + " LIKE '" +
1 producto_eliminar + "'";
9
//Se borra el producto indicado en el campo de texto
2
sqlite.delete(Estructura.TABLE_NAME, consulta, null);
0
2
1 [...]
2
2
2
3

[...]
//Se cierra la conexin abierta a la Base de Datos

sqlite.close();
2
4 [...]
2
5
2
6
2
7
2
8
2
9

Modificar cualquier campo del registro:

[...]
/ / Evento On Click para modifica
public void modificarProducto

1 [...]
2
3 //Evento On Click para modificar un producto de la tabla Ventas. Todos los
campos son modificables, excepto el campo _id
4
public void modificarProducto(View view)
5
{
6
//Se inicializa la clase.
7
basedatos = new MiBaseDatos(this);
8
9
1
0
1
1

//Se establecen permisos de escritura


SQLiteDatabase sqlite = basedatos.getWritableDatabase();

[...]

1
2
[...]
1
3 ContentValues content = new ContentValues();
1
4

//Se aaden los valores introducidos de cada campo mediante


1 clave(columna)/valor(valor introducido en el campo de texto)
5
content.put(Estructura.COLUMN_NAME_PRODUCTO, producto_modificar);
1
content.put(Estructura.COLUMN_NAME_CANTIDAD, cantidad_modificar);
6
1
7

content.put(Estructura.COLUMN_NAME_SECCION, seccion_modificar);

1 [...]
8
1
9 [...]
2

//Se establece la condicin del _id del producto a modificar

String selection = Estructura._ID + " LIKE " + identificador;

2
1

//Se llama al mtodo update pasndole los parmetros para modificar el


2 producto con el identificado como condicin de busqueda
2
int count = sqlite.update(Estructura.TABLE_NAME, content, selection,
2 null);
3
2
[...]
4
2
5 [...]
2
6
2
7

//Se cierra la conexin abierta a la Base de Datos


sqlite.close();

2
8 [...]
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3

8
3
9
4
0

Dentro del Layout se definen los siguientes controles:


Ruta: StockFerreteria/com.academiaandroid.stockferreteria/MainActivity.java:
[...]
<TextView
android:id="@+id/ textVie

[...]

<TextView

android:id="@+id/textView5"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Identificador:" />

7
8

<EditText

android:id="@+id/edIdentificador"

10

android:layout_width="match_parent"

11

android:layout_height="wrap_content" />

12
13

<TextView

14

android:id="@+id/txtProducto"

15

android:layout_width="wrap_content"

16

android:layout_height="wrap_content"

17

android:layout_marginTop="32dp"

18

android:text="Producto:" />

19
20

<EditText

21

android:id="@+id/edProducto"

22

android:layout_width="wrap_content"

23

android:layout_height="wrap_content"

24

android:ems="10" >

25
26
27

<requestFocus />
</EditText>

28
29

<TextView

30

android:id="@+id/textView2"

31

android:layout_width="wrap_content"

32

android:layout_height="wrap_content"

33

android:layout_marginTop="34dp"

34

android:text="Seccin:" />

35
36

<Spinner

37

android:id="@+id/spinnerSeccion"

38

android:layout_width="wrap_content"

39

android:layout_height="wrap_content"

40

android:layout_marginTop="24dp" />

41
42

<TextView

43

android:id="@+id/textView3"

44

android:layout_width="wrap_content"

45

android:layout_height="wrap_content"

46

android:layout_marginTop="35dp"

47

android:text="Total:" />

48
49

<EditText

50

android:id="@+id/edCantidad"

51

android:layout_width="wrap_content"

52

android:layout_height="wrap_content"

53

android:layout_marginRight="56dp"

54

android:ems="10" />

55
56

[...]

57

[...]

58
59

<Button

60

android:id="@+id/btnGuardar"

61

android:layout_width="wrap_content"

62

android:layout_height="wrap_content"

63

android:layout_alignParentRight="true"

64

android:layout_alignTop="@+id/linearLayout1"

65

android:onClick="guardarRegistro"

66

android:text="Guardar" />

67
68

<Button

69

android:id="@+id/btnEliminar"

70

android:layout_width="wrap_content"

71

android:layout_height="wrap_content"

72

android:layout_alignRight="@+id/btnGuardar"

73

android:layout_below="@+id/btnGuardar"

74

android:layout_marginTop="25dp"

75

android:onClick="borrarProducto"

76

android:text="Eliminar" />

77
78
79

<Button
android:id="@+id/btnModificar"

80

android:layout_width="wrap_content"

81

android:layout_height="wrap_content"

82

android:layout_alignRight="@+id/btnEliminar"

83

android:layout_below="@+id/btnEliminar"

84

android:layout_marginTop="28dp"

85

android:onClick="modificarProducto"

86

android:text="Modificar" />

87
88
89

<Button
android:id="@+id/btnBuscar"

90

android:layout_width="wrap_content"

91

android:layout_height="wrap_content"

92

android:layout_alignLeft="@+id/btnGuardar"

93

android:layout_below="@+id/btnModificar"

94

android:layout_marginTop="28dp"

95

android:onClick="buscarProducto"

96

android:text="Buscar" />

97
98
99

[...]

En la imagen de abajo, vemos el Layout de la aplicacin:

Como soporte para nuestra Activity principal se declaran dos clases:

Una Clase Abstracta que implementa la interfaz BaseColumns, para


establecer el nombre de la tabla, y los campos producto, cantidad y
seccion definido como Constantes, ya que su valor no ser modificado:
Ruta:
StockFerreteria/com.academiaandroid.stockferreteria/EstructuraDatos.ja
va:

[...]
public static abstract c
{
public static final St

[...]

public static abstract class Estructura implements BaseColumns

public static final String TABLE_NAME = "Ventas";

public static final String COLUMN_NAME_PRODUCTO = "producto";

public static final String COLUMN_NAME_CANTIDAD = "cantidad";

public static final String COLUMN_NAME_SECCION = "seccion";

9
10

[...]

Y la Clase MiBaseDatos, que hereda de la Clase SQLiteOpenHelper,


que implementar los mtodos OnCreate() y OnUpgrade() encargados
de crear y actualizar la Base de Datos:
Ruta:
StockFerreteria/com.academiaandroid.stockferreteria/MiBaseDatos.java:

[...]
public class MiBaseDatos exte
/ / Se declaran e inicializan las va

1 [...]
2
3

public class MiBaseDatos extends SQLiteOpenHelper{

4 //Se declaran e inicializan las variables encargadas de almacenar las


consultas para crear la tabla 'Ventas',
5
//y las consultas de eliminar/crear la Base de Datos 'Ferreteria.sqlite'.
6
private static final String TEXT_TYPE = " TEXT";
7
private static final String COMMA_SEP = ",";
8
private static final String SQL_CREATE_ENTRIES =
9
"CREATE TABLE " + Estructura.TABLE_NAME + " (" +
1
0
Estructura._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
1
1
1

Estructura.COLUMN_NAME_PRODUCTO + TEXT_TYPE + COMMA_SEP +


Estructura.COLUMN_NAME_CANTIDAD + TEXT_TYPE + COMMA_SEP +
Estructura.COLUMN_NAME_SECCION + TEXT_TYPE + " )";

2
1 private static final String SQL_DELETE_ENTRIES =
3
"DROP TABLE IF EXISTS " + Estructura.TABLE_NAME;
1
public static final int DATABASE_VERSION = 1;
4
public static final String DATABASE_NAME = "Ferreteria.sqlite";
1
5
1 [...]
6
[...]
1
7 //Mtodo para crear la Tabla que recibe la consulta Transact-SQL
1 @Override
8 public void onCreate(SQLiteDatabase db) {
1 db.execSQL(SQL_CREATE_ENTRIES);
9
}
2
0
2 //Mtodo que elimina la tabla y vuelve a llamar al mtodo que la crea
1
@Override
2
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
2
db.execSQL(SQL_DELETE_ENTRIES);
2
3 onCreate(db);
2 }
4
[...]
2
5
2
6
2
7
2
8
2
9
3

0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
base de datosSQLite

This Post Has 10 Comments

1.

josu
12/06/2015 a las 11:15 pm

Aunque le d permisos ya no me deja descargar el proyecto!


Responder

1.

Administrador
16/06/2015 a las 10:35 am

Disclpanos Josu pero se haba quedado sin contestar tu comentario.


En principio, no nos estn comentando ningn problema los usuarios, y hay
descargas ms o menos continuas de este proyecto. Te sigue ocurriendo?
En caso de que s, te sale algn tipo de mensaje o error?.
Saludos
Responder

2.

Josue Castillo
15/09/2015 a las 12:13 am

Puedes mandarme el proyecto a mi corre porfa! ya que no puedo descargarlo


Responder

1.

Academia Android
15/09/2015 a las 1:31 pm

Hola Josue,
vamos a cambiar el modo de descargarlo. Debe estar solucionado en una
media hora.
Saludos
Responder

3.

Mario
29/01/2016 a las 8:08 pm

Hola Muchas gracias por la informacin, tengo la siguiente duda, me gustara que al
seleccionar el checkbox se vea en una base de datos, como lo puedo hacer, gracias.
Responder

1.

Academia Android
30/01/2016 a las 10:01 am

Hola Mario, disculpa pero no entendemos bien tu pregunta.


En cualquier caso, a cuestiones de este tipo, podemos dar soporte en nuestro
curso de Aplicaciones Android con bbdd SQLite donde contis con la ayuda
de un tutor especializado.
Gracias
Responder

4.

Ricardo
01/02/2016 a las 2:28 am

Hola por favor me podrian mandar a mi correo, no lo puedo descargar. Porfavor


Gracias.
Responder

1.

Academia Android
01/02/2016 a las 1:26 pm

Hola Ricardo, hemos comprobado con varios navegadores (Chrome y


Firefox) que la descarga funciona bien. Puedes reintentarlo por si ha sido
algo puntual?
Si te falla nuevamente nos puedes decir qu error te da?
Gracias
Responder

5.

Ruben
07/04/2016 a las 9:15 pm

disculpa si en ves de hacerlo con los spinner lo quiero hacer con radiobutton y
checkbox como lo podria hacer para guardarlos en la base de datos y luego
recuperarlos ???
Responder

1.

Academia Android
15/04/2016 a las 1:40 pm

Perdona Rubn pero haba quedado el mensaje en el filtro spam.Esperamos


que hayas resuelto ya tu duda entretanto.
A travs de estos comentarios intentamos atender incidencias que podis
encontrar en nuestros contenidos (problemas para descargar algn proyecto,
errores que podis detectar en algn tutorial) y por supuesto escuchar
vuestras sugerencias.
Para cuestiones de soporte, os rogamos consultis los cursos online que
tenemos disponibles, como el de bbdd Sqlite donde contis un tutor os va a
prestar toda la ayuda necesaria.
Gracias
Responder
Deja un comentario

Tu direccin de correo electrnico no ser publicada. Los campos obligatorios estn


marcados con *
Nombre *

Correo electrnico *
Web
Para evitar robots, por favor completa esta sencilla operacin *

Base de datos SQLite


SQLite es un motor de base de datos relacional de cdigo abierto y muy
potente, eso hace que actualmente sea muy usado por los desarrolladores. Sus
principales caractersticas son que precisa de poca configuracin, no necesita
ningn servidor ya que directamente lee y escribe en archivos de disco
normales, ocupa muy poco tamao en el almacenamiento y a parte es
multiplataforma.

Android ofrece de serie soporte total para la creacin y administracin de base


de datos SQLite a travs del paquete "android.database.sqlite". Solo tendremos
que definir las sentencias SQL para crear y gestionar la base de datos.

En este caso nos vamos a centrar en:


Creacion y gestion de una base de datos SQLite
Copia base de datos existente a nuestra aplicacion

1. Creacin base de datos SQLite

Para poder crear bases de datos en nuestra aplicacin debemos usar las clases
hijas de "SQLiteOpenHelper". Que nos pide crear un constructor y sobreescribir
dos mtodos:
"onCreate(SQLiteDatabase db)"
"onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)"
El primero se encargara de crear las tablas si no existen y el segundo las
actualizara si nos es necesario (imaginemos que creamos una tabla con 2
columnas y mas adelante nos hace falta aadir mas columnas, con este
mtodo podramos hacerlo pasndole como parmetro la versin de la tabla
antigua y la versin de la nueva tabla).

Dentro de una base de datos podemos crear tantas tablas como nos sea
necesario, su estructura y la que usaremos en el ejemplo tendr la siguiente
forma:
id

nombre

telefono

email

Pedro

111111111

pedro@DB.es

Sandra

111111111

sandra@DB.es

Maria

111111111

maria@DB.es

Daniel

111111111

daniel@DB.es

As que vamos a verlo en un ejemplo:


public class MiBaseDatos extends SQLiteOpenHelper {

private static final int VERSION_BASEDATOS = 1;

// Nombre de nuestro archivo de base de datos


private static final String NOMBRE_BASEDATOS =
"mibasedatos.db";

// Sentencia SQL para la creacin de una tabla


private static final String TABLA_CONTACTOS = "CREATE TABLE
contactos" +
"(_id INT PRIMARY KEY, nombre TEXT, telefono INT,
email TEXT)";

// CONSTRUCTOR de la clase
public MiBaseDatos(Context context) {
super(context, NOMBRE_BASEDATOS, null, VERSION_BASEDATOS);
}

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(TABLA_CONTACTOS);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLA_CONTACTOS);
onCreate(db);
}
}
Como vemos en el ejemplo, en muy pocas lineas de cdigo podemos crear una
tabla en nuestro archivo de base de datos.
Lo primero que hacemos es crear tres variables:

NOMBRE_BASEDATOS: sera el nombre de nuestro archivo de base de datos


VERSION_BASEDATOS: la versin de nuestra base de datos
TABLA_CONTACTOS: un string que contiene una sentencia SQL para la creacin
de una tabla llamada contactos. Lo que tenemos en parentesis son las
columnas, un ndice INT primario (no es obligatorio pero si muy recomendable
para no tener problemas a la hora de insertar, modificar o borrar alguna fila ya
que es un valor nico), un nombre TEXT, un telefono INT y un e-mail TEXT.
Como podemos ver hay que especificar que tipo de datos va a manejar esa
columna (TEXT, NUM, INT, REAL, ...)
La sintaxis SQL es muy extensa y aqu nos vamos a centrar en lo justo y
necesario si deseas conocer mas sobre ella te recomiendo que visites tu pagina
web SQLite.
Seguimos con el constructor de la clase que nos pide como parmetros un
context, el nombre del archivo de la base de datos, un CursorFactory que no lo
vamos a necesitar y por lo tanto lo ponemos a null y la versin de nuestra base
de datos.
Comentar que para gestionar la base de datos y la clase que estamos creando,
vamos a usar mtodos de la clase "SQLiteDatabase".
Y para terminar la clase sobreescribimos los mtodos onCreate y onUprade
usando el mtodo "execSQL()" que nos pide como parametro una unica
sentencia SQL que no sea un SELECT o cualquier otra sentencia que devuelva
datos. Entonces en el onCreate simplemente creamos la tabla si no existe y en
el onUpgrade borramos la tabla si existe y creamos una nueva.

2. Gestionar base de datos


Para gestionar la base de datos vamos a crear unos mtodos personalizados
para leer, escribir, modificar y eliminar registros de nuestra tabla. Aunque
tambin podramos usar sentencias SQL con el mtodo execSQL, pero este no
va a ser el caso.

2.1 Insertar registros


public void insertarCONTACTO(int id, String nom, int tlf, String
email) {

SQLiteDatabase db = getWritableDatabase();
if(db != null){
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.insert("contactos", null, valores);
db.close();
}
}
Creamos un mtodo "insertarCONTACTO" y como parmetros los datos que
queremos insertar en la tabla (id, nombre, telefono, email). Dentro del mtodo
creamos una instancia de la clase "SQLiteDatabase" y usamos su mtodo
"getWritableDatabase()" para poder escribir en la base de datos. Encapsulamos
todo en un if por si acaso la base de datos no existe y ya dentro del if creamos
una instancia de la clase "ContentValues" que como su nombre indica es un
almacenador de un conjunto de datos. Usamos el metodo "put(key, value)" que
nos pide como primer parmetro "key" el nombre donde establecer el valor
almacenado y como segundo parmetro el valor que queremos almacenar. Una
vez almacenamos los datos insertamos una fila en la tabla usamos el mtodo
"insert(table, nullColumnHack, values)" que nos pide el nombre de la tabla
"table", un segundo parmetro en caso de que necesitemos insertar valores
nulos en la tabla "nullColumnHack" en este caso lo dejaremos pasar ya que no
lo vamos a usar y por lo tanto lo ponemos a null y como tercer parmetro
"values" nos pide un ContentValues. Para concluir deberemos cerrar la base de
datos con el mtodo "close()".

2.2 Modificar registros


public void modificarCONTACTO(int id, String nom, int tlf, String
email){

SQLiteDatabase db = getWritableDatabase();
ContentValues valores = new ContentValues();
valores.put("_id", id);
valores.put("nombre", nom);
valores.put("telefono", tlf);
valores.put("email", email);
db.update("contactos", valores, "_id=" + id, null);
db.close();
}
Prcticamente es igual que el anterior mtodo pero con la excepcin de que
aqu estamos usando el mtodo "update(table, values, whereClause,
whereArgs)" para actualizar/modificar registros de nuestra tabla. Este mtodo
nos pide el nombre de la tabla "table", los valores a modificar/actualizar
"values" (ContentValues), una condicin WHERE "whereClause" que nos sirve
para indicarle que valor queremos que actualic (en este caso cogemos como
referencia la id de nuestro contacto) y como ultimo parmetro "whereArgs"
podemos pasarle los valores nuevos a insertar, en este caso no lo vamos a
necesitar por lo tanto lo ponemos a null. Para terminar deberemos cerrar
siempre nuestra base de datos con el mtodo "close()".

2.3 Borrar registros


public void borrarCONTACTO(int id) {
SQLiteDatabase db = getWritableDatabase();
db.delete("contactos", "_id="+id, null);
db.close();
}
Para borrar registros usaremos el mtodo "delete(table, whereClause,
whereArgs)" que nos pide el nombre de la tabla "table", el registro a borrar
"whereClause" que tomaremos como referencia su id y como ultimo parmetro

"whereArgs" los valores a borrar.

2.4 Leer registros


Para leer registros vamos a crear una clase "Contactos" con un constructor y
varios mtodos get/set para convertir una fila de la tabla en un objeto y nos
sea mas fcil acceder a cualquier valor de ese registro. Los mtodos get/set
simplemente son mtodos para recuperar o establecer un valor del objeto
Contactos.

public class Contactos {

private int id;


private String nombre;
private int telefono;
private String email;

// Constructor de un objeto Contactos


public Contactos(int id, String nombre, int telefono, String
email) {
this.id = id;
this.nombre = nombre;
this.telefono = telefono;
this.email = email;
}

// Recuperar/establecer ID
public int getID() {
return id;
}

public void setID(int id) {


this.id = id;
}

// Recuperar/establecer NOMBRE
public String getNOMBRE() {
return nombre;
}
public void setNOMBRE(String nombre) {
this.nombre = nombre;
}

// Recuperar/establecer TELEFONO
public int getTELEFONO() {
return telefono;
}
public void setTELEFONO(int telefono) {
this.telefono = telefono;
}

// Recuperar/establecer EMAIL
public String getEMAIL() {
return email;
}
public void setEMAIL(String email) {
this.email = email;

}
}
Una vez creada nuestra clase Contactos volvemos a la clase "MiBaseDatos"
para crear los mtodos de lectura de un registro y lectura de todos los registros
de la tabla.

2.4.1 Leer un registro


Para realizar consultas a la base de datos podremos utilizar cualquiera de estos
dos mtodos:

query(table, columns, selection, selectionArgs, groupBy, having, orderBy,


limit) - Mtodo que usaremos en el ejemplo, como se puede observar
recibe muchos parametros que son utilizados para crear la declaracin
SQL.

rawquery(sql, selectionArgs) - Este mtodo es mucho mas simple que el


anterior, directamente recibe una declaracin SQL como primer
parmetro y un segundo parmetro opcional (Recomendado para los que
tengan experiencia en lenguaje SQL, Gracias al usuario por el
comentario !)

Los dos mtodos expuestos nos devolvern un Cursor que podremos recorrer
para recuperar todos los registros de la base de datos. Vamos a continuar con
el atculo y vamos a crear el mtodo para recuperar un registro:

public Contactos recuperarCONTACTO(int id) {


SQLiteDatabase db = getReadableDatabase();
String[] valores_recuperar = {"_id", "nombre", "telefono",
"email"};
id,

Cursor c = db.query("contactos", valores_recuperar, "_id=" +


null, null, null, null, null);
if(c != null) {
c.moveToFirst();

}
Contactos contactos = new Contactos(c.getInt(0),
c.getString(1),
c.getInt(2), c.getString(3));
db.close();
c.close();
return contactos;
}
Este mtodo devuelve un objeto Contactos con los datos del contacto (id,
nombre, telefono, email). En este caso como queremos leer hacemos uso del
mtodo "getReadableDatabase()". Creamos una variable "valores_recuperar"
con las columnas que queremos recuperar, en este caso vamos a recuperar
todos los datos de un registro. Continuamos creando un "Cursor" que se
encarga de devolver el resultado de un registro de la tabla y lo almacena en la
memoria, le aplicamos el mtodo:
query(table, columns, selection, selectionArgs, groupBy, having, orderBy, limit)
Con este mtodo conseguimos leer un registro de la tabla. Como primer
parmetro "table" nos pide el nombre de la tabla , "columns" las columnas que
queremos recuperar, con "selection" le indicamos el registro a recuperar (en
este caso recuperamos con el id), o los registros a recuperar "selectionArgs",
"groupBy" para agrupar los registros consultados , "having" es un filtro para
incluir los registros en el cursor (este parmetro se usara con groupBy),
"orderBy" para ordenar las filas y "limit" para limitar el numero de filas
consultadas.
Con el mtodo "moveToFirst()" ponemos el cursor al inicio de los datos
almacenados. Lo encapsulamos en un if por si acaso no hay datos
almacenados.
Continuamos creando un objeto "Contactos" para almacenar los datos
consultados de un registro, y los vamos recuperando del cursor con mtodos
get indicando la posicin de la columna.
Para terminar debemos cerrar la base de datos y el cursor.

2.4.2 Leer todos los registro

public List<Contactos> recuperarCONTACTOS() {


SQLiteDatabase db = getReadableDatabase();
List<Contactos> lista_contactos = new
ArrayList<Contactos>();
String[] valores_recuperar = {"_id", "nombre", "telefono",
"email"};
Cursor c = db.query("contactos", valores_recuperar,
null, null, null, null, null, null);
c.moveToFirst();
do {
Contactos contactos = new Contactos(c.getInt(0),
c.getString(1),
c.getInt(2), c.getString(3));
lista_contactos.add(contactos);
} while (c.moveToNext());
db.close();
c.close();
return lista_contactos;
}
El mtodo que usamos en este casp es muy similar al de leer un registro pero
en este caso no especificamos que registro queremos recuperar, por lo tanto
ponemos su parmetro a null. A parte creamos una variable "lista_contactos"
donde almacenaremos todos los registros de la tabla en objetos contactos. En
el bucle do-while usamos el mtodo "moveToNext()" como parmetro que se
encargara de pasar al siguiente registro de la tabla y por lo tanto recorrer todos
los registros de la tabla.

3. Uso de nuestra base de datos en


una Activity
public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MiBaseDatos MDB = new


MiBaseDatos(getApplicationContext());

// Escribimos 4 registros en nuestra tabla


MDB.insertarCONTACTO(1, "Pedro", 111111111,
"pedro@DB.es");
MDB.insertarCONTACTO(2, "Sandra", 222222222,
"sandra@DB.es");
MDB.insertarCONTACTO(3, "Maria", 333333333,
"maria@DB.es");
MDB.insertarCONTACTO(4, "Daniel", 444444444,
"daniel@DB.es");

// Recuperamos los 4 registros y los mostramos en el log


Log.d("TOTAL",
Integer.toString(MDB.recuperarCONTACTOS().size()));
int[] ids = new int[MDB.recuperarCONTACTOS().size()];
String[] noms = new
String[MDB.recuperarCONTACTOS().size()];

int[] tlfs = new int[MDB.recuperarCONTACTOS().size()];


String[] emls = new
String[MDB.recuperarCONTACTOS().size()];
for (int i = 0; i < MDB.recuperarCONTACTOS().size(); i++)
{
ids[i] = MDB.recuperarCONTACTOS().get(i).getID();
noms[i] = MDB.recuperarCONTACTOS().get(i).getNOMBRE();
tlfs[i] =
MDB.recuperarCONTACTOS().get(i).getTELEFONO();
emls[i] = MDB.recuperarCONTACTOS().get(i).getEMAIL();
emls[i]);

Log.d(""+ids[i], noms[i] + ", " + tlfs[i] + ", " +

// Modificamos el registro 3
MDB.modificarCONTACTO(3, "PPPPP", 121212121,
"xxxx@xxxx.es");

// Recuperamos el 3 registro y lo mostramos en el log


int id = MDB.recuperarCONTACTO(3).getID();
String nombre = MDB.recuperarCONTACTO(3).getNOMBRE();
int telefono = MDB.recuperarCONTACTO(3).getTELEFONO();
String email = MDB.recuperarCONTACTO(3).getEMAIL();
Log.d(""+id, nombre + ", " + telefono + ", " + email);

// Borramos el registro 3
MDB.borrarCONTACTO(3);
}

}
Lo primero que hacemos es crear una instancia de nuestra clase "MiBaseDatos"
pasndole como parmetro un contexto.
Para insertar registros llamamos al mtodo "insertarCONTACTO(id, nom, tlf,
email)" y simplemente le indicamos los valores a insertar.
A la hora de recuperar registros hacemos uso del mtodo
"MDB.recuperarCONTACTOS.size()" que nos devuelve el numero de registros de
la tabla, sabiendo esto podemos crear 4 arrays con ese tamao para almacenar
los datos separados por categora. Con el mtodo "get(i)" recuperamos un
registro de la tabla y despus con los mtodos "getID()", "getNOMBRE()",
"getTELEFONO()" y "getEMAIL()" vamos recuperando los datos de ese registro.
Para terminar mostramos todo en el log.
Podemos modificar un registro de nuestra tabla con el mtodo
"modificarCONTACTO(id, nom, tlf, email)". Como primer parmetro indicaremos
el registro a modificar y los siguientes parmetros sern los nuevos valores
para ese registro. Mostramos el nuevo registro en el log.
Para concluir podemos borrar registros de la tabla con el mtodo
"borrarCONTACTO(id)" que nos pide como parmetro la id del registro a borrar.

CODIGO DE EJEMPLO: DESCARGAR

4. Copiar base de datos existente


En ocasiones ser necesario incluir a nuestro proyecto un archivo de base de
datos ya creado. O podriamos crearlo nosotros mismos con cualquiera de estos
dos gestores de bases de datos:
SQLite Database Browser (Gratuita, multiplataforma y de cdigo abierto)
Valentina estudio (Aplicacin multiplataforma recomendada en los
comentarios)
En este caso incluiremos el archivo de base de datos en la carpeta assets de
nuestro proyecto. Y por ejemplo crear un mtodo personalizado en nuestra
Activity principal y copiar la base de datos de la carpeta assets a la carpeta

privada de base de datos de nuestra aplicacin. A continuacin dejo un


ejemplo:
private void copiarBaseDatos() {
String ruta = "/data/data/com.example.sqlite/databases/";
String archivo = "contactos.db";
File archivoDB = new File(ruta + archivo);
if (!archivoDB.exists()) {
try {
InputStream IS =
getApplicationContext().getAssets().open(archivo);
OutputStream OS = new FileOutputStream(archivoDB);
byte[] buffer = new byte[1024];
int length = 0;
while ((length = IS.read(buffer))>0){
OS.write(buffer, 0, length);
}
OS.flush();
OS.close();
IS.close();
} catch (FileNotFoundException e) {
Log.e("ERROR", "Archivo no encontrado, " +
e.toString());
} catch (IOException e) {
Log.e("ERROR", "Error al copiar la Base de Datos, " +
e.toString());
}
}

No me voy a parar a explicar esto ya que tenemos en este mismo blog un


articulo que trata sobre como manejar los archivos. Simplemente comentar que
usaramos el mtodo al comienzo del onCreate para tener disponible la base de
datos desde el primer comienzo de la aplicacin, a parte comentar que en la
ruta "/data/data/'NOMBREdelPAQUETE'/databases" se encuentran nuestros
archivos de base de datos. Para mas informacin sobre manejar archivos
visitar: Opciones de almacenamiento.
Enviar por correo electrnicoEscribe un blogCompartir con TwitterCompartir con
FacebookCompartir en Pinterest
65 comentarios:
1.
Annimo12 abril, 2013 14:41

genial!! me ha ayudado un montn gracias


Responder
2.
Annimo05 agosto, 2013 13:45

Muchas gracias. El punto 4 me ha aclarado mucho las ideas.


Para los que tengais algo de experiencia con el lenguaje SQL, os recomiendo
utilizar el mtodo rawquery en vez de query, ya que te permite insertar la sentencia
SQL tal cual.
Un saludo.
Responder
Respuestas

1.
Luis Albes06 agosto, 2013 22:30

Gracias por la anotacin, porque en el artculo no lo tengo comentado. Haber


si le hecho un ojo un da y lo explico un poco
Un saludo !!

2.

Cristian Villamil12 julio, 2015 23:08

Muchas gracias, el raw query me sirvi bastante


Responder
3.
Annimo07 agosto, 2013 14:42

Echa un vistazo a una herramienta gratuita - Valentina Studio. Producto asombroso!


OMI es el mejor gestor de SQLite para todas las plataformas. http://www.valentinadb.com/en/valentina-studio-overview
Responder
Respuestas

1.
Luis Albes07 agosto, 2013 16:00

Gracias por la aplicacion, la proxima vez la tendre en cuenta. La dejo


comentada en el articulo por si le sirve a alguno
Responder
4.
Annimo13 agosto, 2013 18:16

Hola, enhorabuena por el tutorial. He creado una lista expandible utilizando estos
mismos mtodos en la base de datos. El problema surge cuando quiero aadir un
item a un grupo ya existente, habiendo seleccionado previamente ste en un
Spinner. La base de datos consta de dos tablas: una para los grupos y otra para los
hijos. Tambin he creado los mtodos insertar, eliminar, actualizar y obtener en
ambos casos. Debo crear algn mtodo nuevo para poder aadir un elemento a un
grupo ya creado? Cul es la solucin? Gracias, es urgente.
Responder
Respuestas

1.
Luis Albes26 agosto, 2013 23:13

Gracias y perdona por tardar en contestar pero es que llevo un mes muy
liado.
No se realmente lo que estas haciendo pero teniendo la base de este tutorial
puedes crear los mtodos que te sean necesarios para aadir elementos a una
tabla, eso ya depende de tus necesidades. Deberas crear un mtodo que
inserte elementos en la tabla dependiendo del grupo seleccionado, para
luego poder recuperarlos segn su grupo.
Responder
5.
Annimo05 septiembre, 2013 21:13

Gracias muy til.


Responder

6.
walter lopez28 septiembre, 2013 19:24

tengo un problema con mi base, tiene 5 tablas.... lo q pasa esq no se si se crea mi


base, y bueno cuando quiero hacer un select a sin haber insertado ningun dato aun,
me da un error "no such table"; pareciera como q no existe la tabla... xq si fuera por
q no tiene datos me imagino q simplemente me devolveria un cursor vacio...
ayudaaaaaa...!!!!
Responder
Respuestas

1.
Luis Albes22 noviembre, 2013 11:13

Debes utilizar el constructor de la base de datos en tu codigo android para


que te cree la base de datos.
Responder
7.
Azucarados19 octubre, 2013 20:36

Gracias! Es todo muy claro y funcional, pero tengo un problema. En cualquiera de


los mtodos dentro de la clase que hereda de SQLiteOpenHelper que utilizo la
sentencia: SQLiteDatabase db = getReadableDatabase(); lanza una
SQLiteException. Alguien sabe porqu me pasa? (cabe aclarar que soy nuevo en la
programacin Android).
Responder
Respuestas
1.
Azucarados19 octubre, 2013 20:53

El error era mo (como era de esperarse). Tena una base de datos con una
versin ms grande que la que haba declarado. Saludos!
Responder

8.
RedRum11 noviembre, 2013 16:34

Excelente!!!
Responder
9.
Annimo18 noviembre, 2013 02:22

como consulto la fecha actual en sqlite xq en sql seria algo como esto select
getdate() y listo.... pero en sqlite no funciona
Responder

Respuestas

1.
Luis Albes22 noviembre, 2013 11:14

Consulta directamente la fecha actual a Android. En google tendras mil


ejemplos

2.
Jorge Luis Villavicencio Correa17 marzo, 2014 21:45

https://www.youtube.com/user/anderwelt23
La fecha actual en sqlite, puede ser consultada dentro de la misma base de
datos sqlite de la siguiente manera: date('now'). Saludos!!
Responder
10.
Alejandra Ramirez05 diciembre, 2013 22:03

tengo una tabla con 4 campos y hasta ahi todo bien guardo y leo los datos sin
problema, pero cuando le quiero agregar una columna al momento de leer los datos
ya no lo hace y me manda error y ya no me abra la activity, y lo extrao es que
cuando guardo datos me dice que los guardo correctamente, el problema es al
leerlos. Espero alguien me pueda ayudar. Gracias!!!!
Responder
Respuestas

1.
Luis Albes10 diciembre, 2013 13:51

Lo unico que te puedo decir es que observes bien el Logcat ya que te


informara porque se produce el error y a traves de esa informacion podras
corregir la excepcion. Si tienes problemas copia el error por aqui haber si te
puedo ayudar

2.
Alejandra Ramirez10 diciembre, 2013 17:00

Esto es lo que me pone en el logcat, espero que con esta informacion me


puedas ayudar u orientar en lo que puede ser, ya que apenas estoy
aprendiendo esta plataforma. Gracias!!!!
Caused by: android.database.sqlite.SQLiteException: no such solumn:
Titular while compiling: Select _id, Dependencia,Horario, Requisitos,
Titular from Tramites
at android.database.sqlite.SQLiteProgram.native_compile(Native Method)
at
android.database.sqlite.SQLiteProgram.compile(SQLiteProgram.java:110)
at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:59)
at android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:49)
.....

3.
Luis Albes11 diciembre, 2013 00:31

Ahi simplemente te indica que no existe la columna Titular. Debes


comprobar que se crea y se recupera bien la columna, algo debes tener mal
en el codigo
Responder

11.
francisco roman13 diciembre, 2013 22:51

Hola, oye me surgi una duda con respecto al tutorial, cada tema lo estas haciendo
en una nueva clase?
Responder
Respuestas

1.
Luis Albes14 diciembre, 2013 15:16

Perdname pero no entiendo muy bien lo que quieres preguntar, podras


explicar a que temas te refieres y que clases

2.
francisco roman16 diciembre, 2013 22:14

Osea, que si cada tema que estas haciendo (creacin de la base de datos,,
insertar datos) los hiciste cada uno en una nueva clase o todos van en una
sola, o de no ser as, donde los escribiste??

3.
Luis Albes17 diciembre, 2013 13:37

Si te descargas el codigo fuente que esta al final del punto 3 veras como esta
estructurado todo. Hay 3 clases, la activity del punto 3, la clase objeto del
punto 2.4 y el resto es la clase de base de datos del punto 1.
Responder

12.
Walter Suazo21 diciembre, 2013 18:42

Excelente tuto, me ayudo a entender lo de las bases de datos, un pregunta, puedo


hacer muchos inserts con una sola linea, me explico; en mysql tu puedes hacer un
insert on tabla (valorA1,valorB1,valorC1),(valorA2,valorB2,valorC2),....,
(valorAn,valorBn,valorCn); puedo hacer eso en sqlite??
Responder
Respuestas

1.
Luis Albes21 diciembre, 2013 19:58

Gracias por el comentario !! Si miras bien el tutorial en el punto 2.4.1 te dice


que puedes utilizar 2 metodos para trabajar con la sqlite. En tu caso imagino

que te refieres a trabajar con sentencias SQL, entonces deberias utilizar el


metodo rawquery pasandole como argumento la sentencia "Insert into ....."
Responder
13.
Annimo23 diciembre, 2013 11:12

cargo la aplicacion en mi android y sale en la pantalla (Hello world!)


Alguien me puede ayudar. Supongo que hay que hacer algo antes.
Responder
Respuestas

1.
Luis Albes28 diciembre, 2013 19:32

La aplicacin no tiene ninguna interface de usuario, es normal que solo te


ocurra eso. Observa la salida del logcat porque muestra la lectura de la base
de datos creada en el ejemplo.
Responder
14.
Annimo28 diciembre, 2013 14:23

Hola
Podias explicarme como puedo hacer un select con el metodo rawquery en el que en
la clausula select me compare con una variable de java
Ej select * from tabla where columna = variable java
Gracias
Responder
Respuestas

1.

Luis Albes28 diciembre, 2013 19:35

No he llegado a utilizar ese mtodo pero puedes probar a crear un string con
la consulta:
String consulta = "select * from tabla...";
Y aplicar ese string al mtodo rawquery:
db.rawquery(consulta, null);
Responder
15.

Jordan Reusche03 enero, 2014 23:01

Te luciste! gracias por la info, me ayudaste en mucho


Responder
16.
Alejandra Ramirez21 enero, 2014 19:04

Hola Luis, necesito implementar la modificacion en una app, pero me manda error,
te pongo el codigo
public long GuardarModi(String [] servicio,String de, String ho, String re, String ti,
String doc, String cos, String tiem, String vi, String dom, String tel, String fa, String
co, String tra) {
// TODO Auto-generated method stub
ContentValues cv=new ContentValues();
cv.put(dependencia,de);
cv.put(horario,ho);
cv.put(requisitos, re);
cv.put(titular, ti);
cv.put(documento, doc);
cv.put(costo,cos);
cv.put(tiempo,tiem);
cv.put(vigencia,vi);
cv.put(domicilio,dom);

cv.put(telefono, tel);
cv.put(fax, fa);
cv.put(correo, co);
cv.put(tramite, tra);
//return nBD.rawquery("Update ");
//servicio=new String [] {"2"};
return nBD.update(N_TABLA,cv,"_id="+ servicio,null);
}
tambien puse el updete de la siguiente manera
return nBD.update(N_TABLA,cv,"_id=?", servicio);
pero de las dos formas me manda el siguiente error
java.lang.nullpointerexception
Espero me puedas ayudar, ya que llevo mucho tiempo atorada con este problema.
Saludos.
Responder
Respuestas

1.
Luis Albes21 enero, 2014 23:49

Doy por hecho que quieres actualizar un registro de la tabla por lo que seria
conveniente que revisaras el punto 2.2 del articulo. En principio los dos
updates parecen correctos a si que el error debe venirte de otro sitio, revisa
bien el logcat porque te dice exactamente donde esta el error en que clase
java y la linea. Ese error es tipico por ejemplo cuando un objeto, variable, ..
es nulo en ese momento de la ejecucion.
2.
Alejandra Ramirez22 enero, 2014 19:23

ya lo resolv, me faltaba abrir la conexin, gracias!!!!


Responder

17.
Annimo29 enero, 2014 22:57

gracias, por la labor.


Responder

18.
Rebeca C. C.20 febrero, 2014 18:37

Hey qu tal? Oye, de casualidad no sabes como podra manejar imgenes en las
bases de datos? D: de verdad que me servira y mucho...
Responder
Respuestas

1.
Luis Albes21 febrero, 2014 14:59

Tienes dos opciones para almacenar una imagen en una columna de la base
de datos:
1.- Almacenar la ruta de la imagen en un String
2.- O almacenar la imagen en forma de BLOB
He estado probando la segunda por curiosidad y un blob simplemente en un
array de bytes. Entonces la cuestion es convertir la imagen a un array de
bytes y ya podrias almacenarla en una columna de la sqlite. Para recuperar la
imagen seria el proceso inverso, convertir el array de bytes en un bitmap.

He visto un par de metodos por google que te pueden servir:


public static byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, stream);
return stream.toByteArray();
}

public static Bitmap getImage(byte[] image) {


return BitmapFactory.decodeByteArray(image, 0, image.length);
}

PD: haber cuando tenga algo de tiempo y editare el articulo ya que me


gustaria mejorarlo un poco por ser el mas visitado el blog.
2.
Frange19 marzo, 2014 21:02

Hola Luis, gracias por hacernos tanto caso y por el blog.


Yo estoy liado con las imagenes tambin, la BBDD funciona bien hasta que
intento meter las fotos. Te resumo lo que he hecho:
-------------------------------CONTACTOS.java:
Aadir el campo "byte[] foto" para el constructor, al igual que tu con los
otros campos.
Aadidos metodos set&get de la fotos tambin con byte[]
---------------------------MiBaseDatos.java:
Aadido "foto BLOB" en el CREATE TABLE
Aadido en insertar, modificar: "valores.put("foto", foto);" pasandole byte[]
Aadido en recuperar(int id) y List recuperar() en valores_recuperar: ,"foto"
El problema lo tengo cuando ejecuta la linea:
Cursor c = db.query("lobos", valores_recuperar, null, null, null, null, null,
null);
Directamente se detiene la aplicacin y no me indica ningun error ni nada :(
y en esta linea siguiente tambin aad:
"Contactos contactos= new Contactos(c.getInt(0), c.getString(1), c.getInt(2),
c.getString(3), c.getBlob(4));"
------------------------------------------------Main.java:
He introducido 4 contactos:
db.insertarANIMAL(1, "Pedro", 111111111, "pedro@DB.es",null);
db.insertarANIMAL(2, "Sandra", 222222222, "sandra@DB.es",null);
db.insertarANIMAL(3, "Maria", 333333333, "maria@DB.es",null);
db.insertarANIMAL(4, "Sonia", 444444444, "sonia@DB.es",null);

Y transformo la imagen en bytes:


foto = BitmapFactory.decodeResource(getResources(),
R.drawable.nopicture);
// convert bitmap to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
foto.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte imageInByte[] = stream.toByteArray();
En principio todo eso lo hace bien.
alguna idea donde est el fallo ?
3.
Frange20 marzo, 2014 00:38

He reducido la busqueda de mi error, en la parte de RecogerContactos


(todos) tengo:
String[] valores_recuperar = {"_id", "nombre", "telefono", "email", "foto"};
Cursor c = db.query("lobos", valores_recuperar, null, null, null, null, null,
null);
c.moveToFirst();
do {
ALobos contactos = new ALobos();
contactos.setID(c.getInt(0));
contactos.setNOMBRE(c.getString(1));
contactos.setTELEFONO(c.getInt(2));
contactos.setEMAIL(c.getString(3));
contactos.setFOTO(c.getBlob(4)); <----------------------------- AQU PETA
lista_contactos.add(contactos);
} while (c.moveToNext());
--------------------------------------------------Llevo toda la tarde y no veo el error, en el main tengo:
Bitmap image =
BitmapFactory.decodeResource(getResources(),R.drawable.oro);
// convert bitmap to byte
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] imageInByte = stream.toByteArray();

db.insertarANIMAL(1, "Pedro", 111111111, "pedro@DB.es",imageInByte);


db.insertarANIMAL(2, "Sandra", 222222222,
"sandra@DB.es",imageInByte);
----------------------Por lo que veo al hacer debug, me va cogiendo bien los datos del
1,Pedro,1111111,pedro@tal
pero al llegar a la imagen peta.
sabes por qu puede ser ? La CREATE TABLE tiene el campo "foto" como
blob

4.
Luis Albes23 marzo, 2014 13:14

Prueba a almacenar en el objeto "ALobos contactos" un bitmap en lugar de


un array de bytes, es decir, en este punto:
contactos.setID(c.getInt(0));
contactos.setNOMBRE(c.getString(1));
contactos.setTELEFONO(c.getInt(2));
contactos.setEMAIL(c.getString(3));
contactos.setFOTO(c.getBlob(4)); <---------------- ESTE
Almacena en ese lugar un bitmap de la siguiente manera:
Bitmap imagen = BitmapFactory.decodeByteArray(c.getBlob(4), 0,
c.getBlob(4).length);
contactos.setFOTO(imagen);
(A parte adapta el constructor y los metodos para que manejen el bitmap en
lugar del array bytes)
En principio la parte de base de datos la estas haciendo bien, el tema de
almacenar los datos en el objeto "ALobos contactos" habria que revisarlo y
ver exactamente cual es el fallo que marca el log.
Responder
19.

Gabriel Barjau06 marzo, 2014 09:05

Hola ante todo muy buen tutorial. Tengo una duda. Quisiera saber como trabajar con
varias tablas. Por ejemplo buscar un registro en la primer tabla, buscar otro registro
en la segunda tabla y grabar.en la tarcer tabla los datos que busque de.la tabla 1 y
2.espero que me puedas ayudar.!
Gracias!
Gabriel
Responder
Respuestas
1.
eloy13 marzo, 2014 18:27

Te digo como yo lo hago.


Tengo una clase que me sirve de fachada ante las conexiones a la base de
datos, llammosla FacadeDB, en sta existe un campo (un objeto) de una
clase que extienda a SQLiteOpenHelper (en mi caso es la nica clase que
extiende a este "ayudante", y es en el mtodo onCreate donde se ejecuta el
cdigo necesario para generar las diferentes tablas con la llamada al mtodo
execSQL), llammosla GeneralDBConnector. Adems la clase FacadeDB,
tambin utiliza otros dos objetos que son los encargados de realizar todo el
conjunto de operaciones CRUD, y en cuyos constructores se les pasa una
copia de la clase GeneralDBConnector (podemos llamarlos ClaseCRUD1,
ClaseCRUD2 y ClaseCRUD3, donde cada uno de ellos realizar este tipo de
operaciones CRUD sobre un nica tabla TABLA_1, TABLA_2, y
TABLA_3). La instanciacin de esos campos utilizados en FacadeDB se
puede hacer en su constructor, de esta manera quedara:
public FacadeDB(Context context) //El objeto Context se lo puedes pasar
desde cualquier activity.
{
general = new GeneralDBConnector(context);
crud1 = new ClaseCRUD1(general);
crud2 = new ClaseCRUD2(general);
crud3 = new ClaseCRUD3(general);
}
Cada una de las clases que realize las conexiones a la base de datos,
guardar una copia de esa clase GeneralDBConnector, as, sus mtodos

constructores (y un mtodo de extraccin por el id) seran algo como(aunque


le hemos pasado un GeneralDBConnector, y el constructor espera un
SQLiteOpenHelper, al ser descendiente una de otra todo est correcto) :
public ClaseCRUD1(SQLiteOpenHelper general)
{
this.general = general;
}
public Clase_1_GuardadaEnDB getClase(int id)
{
SQLiteDatabase db = general.getReadableDatabase();
Clase_1_GuardadaEnDB clase;
String selectQuery = "EXTRACCION DE LA TABLA_1" + id;
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst())
{
clase = new ClaseGuardadEnDB(cursor.geStrin(1).....etc....);
}
db.close();
return clase;
}
De vuelta a la clase Facade, si quieres extraer datos de dos tablas y meterlos
en una nica tabla sera algo como (esto es un mtodo de Facade):
public void sortTable1_and_Table2(int id_1, int id_2)
{
Clase_1_GuardadaEnDB clase1 = crud1.getClase(id_1);
Clase_2_GuardadaEnDB clase2 = crud2.getClase(id_2);
crud3.addClase(clase1, clase2);
}

Para ser ms eficiente... o mejor dicho para tener una mejor estructuracin
de la jerarqua de las clases la clase FacadeDB es en realidad un Singleton,
con lo que su constructor e privado y para instanciarla se utiliza un mtodo
esttico generalmente llamado getInstance, que devuelve un objeto de tipo
static de la clase FacadeDB).

2.

Luis Albes14 marzo, 2014 12:34

Gracias por contestar eloy, ultimamente estoy muy liado y no tengo tiempo
para dedicarlo al blog.
Tu solucion esta bien para los que no tenemos conocimientos en sentencias
SQL. He estado hechando un ojo por google y encontre estos dos hilos en
stackoverflow:
http://stackoverflow.com/questions/2529656/how-can-i-select-records-fromtwo-different-tables-in-one-mysql-query
http://stackoverflow.com/questions/12890071/select-from-multiple-tablesmysql
En los dos casos explica como hacer una consulta a una base de datos con
dos tablas. (Las dos formas de hacerlo son validas, lo unico que al hacerlo
por sentencias SQL te ahorras algo mas de codigo).
La forma de hacerlo ya depende del desarrollador, en google hay muchos
tutoriales sobre el uso de la sintaxis SQL.
Responder
20.
eloy13 marzo, 2014 13:28

Hola, buenos das.


Quiero hacer la actualizacin de una entrada de una tabla con el mtodo db.update
(siendo db una instancia de la clase SQLiteDatabase). Para un slo "ingrediente" en
la clausula where y sus argumentos sera algo como:
update(TABLA, nuevosValores, "campoX = ?", new String[]
{"argumento_para_coincidencia_del campoX"});
Pero... si quisiera hacer que hubiera ms de un criterio en la clausula where... cmo
se hara??
update(TABLA, nuevosValores, "campoX = ? AND campoY=?", new String[]
{"arg_campoX", "arg_campoY"});
Estara bien el AND, o habra que poner una coma entre ambos campos? o qu?

GRACIAS.
Responder
Respuestas

1.
Luis Albes14 marzo, 2014 13:03

Estoy un poco perdido en sintaxis SQL pero por lo que he podido ver en
google tu segundo ejemplo seria el valido:
update(TABLA, nuevosValores, "campoX = ? AND campoY=?", new
String[] {"arg_campoX", "arg_campoY"});
Se puede utilizar AND y OR, al igual que se utiliza en java. Hechale un ojo a
este articulo que te sacara de dudas:
http://www.w3schools.com/sql/sql_and_or.asp
Responder
21.
Annimo19 marzo, 2014 09:56

Hola muchas gracias por el tutorial. Tengo una pregunta a la que no paro de darle
vueltas e intentar. Si quisiese hacer un boton consultar para que al pulsar me
saliesen todos los contactos de la base de datos como lo tendra que hacer? gracias,
espero que alguien me pueda ayudar :(
Responder
Respuestas
1.
Frange19 marzo, 2014 22:03

Lo tienes practicamente hecho. Necesitas hacer un listener del boton


"CONSULTA":
ponerlo en el mainactivity-OnCreate:

Button Calibrar=(Button)
findbyid(R.id.nombredelbotoneneldiseodepantallalayout)
Calibrar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
seleccion();
}
});
Y crear una funcion seleccion:
private void seleccion(){
//Recorrer la tabla
int total=db.recuperarContacto().size();
for (int j=0;j<total;j++)
{
//Hacer lo que quieras con cada elemento (mostrar por ejemplo en textview o
listas)
int[] ids = new int[db.recuperarContacto().size()];
ids[j] = db.recuperarANIMAL().get(i).getID();
noms[j] = db.recuperarContacto().get(i).getNOMBRE();
tlfs[j] = db.recuperarContacto().get(i).getTELEFONO();
emls[j] = db.recuperarContacto().get(i).getEMAIL();
//Esas variables son las que tienes que poner donde quieras
}
}

2.
Deivid Salmeron Vicente01 mayo, 2014 02:37

podrias hacer uno asi pero completo sacando una lista


Responder

22.
Deivid Salmeron Vicente30 abril, 2014 23:23

Amigo haces tutoriales ?? estara bueno que subieras uno de este tema porque eres
un maestro para esto mi profesor no ensea nada de esto
Responder
Respuestas

1.
Deivid Salmeron Vicente01 mayo, 2014 00:17

amigo y una pregunta porque no me sale nada en el layout me sale solo el


hello word

2.
Luis Albes01 mayo, 2014 13:27

Correcto, en la pantalla del movil no muestra nada. Solamente lo hace en el


logcat de eclipse.

Realmente no busco hacer tutoriales, simplemente utilizo el blog a modo de


archivo. Voy repasando la guia para desarrolladores y cuando tengo tiempo
subo algun resumen al blog. Pero ultimamente ando muy liado con un par de
proyectos y no tengo tiempo para dedicarlo al blog.
PD: Yo os agradezco el seguimiento pero con lo que hay publicado en el
blog es mas que suficiente para ir aprendiendo a hacer las cosas.
Responder
23.
Annimo02 julio, 2014 19:49

hola amigo muchas gracias por el tutorial


tenia una preguntita, en la parte 4
puedo copiar una base de datos externa
es decir la ruta puede ser la direccion ip de otra maquina donde este guardada la
base de datos?
Responder
24.
Jonathan Cortes31 agosto, 2014 07:27

Buenas excelente tu explicacin me sirvi de mucho.


Mi consulta es como evitar que los datos los borre el usuario los registros que se
hicieron directamente desde el mvil. Como evitar que el usuario no borre los datos
en administracin de aplicaciones del mvil.
Responder

25.
Dante Valencia01 septiembre, 2014 18:07

una duda, el modo de crear los mtodos para leer y registrar datos es el mismo?
Responder
26.
Annimo05 octubre, 2014 20:20

//Recuperamos los registros y los mostramos


tengo mas de 500 datos tarda mucho al ejecutar la aplicacion como podria
solucionar esa parte?
Responder

27.
Jair Tavera17 noviembre, 2014 00:38

Es el mejor ejemplo, el mas claro que pude conseguir,


muchas gracias me ayudo un montn.
Responder
28.
Annimo19 enero, 2015 16:59

hola, en la parte de copiar archivos me marca con rojo lo siguiente:


InputStream IS = getApplicationContext().getAssets().open(archivo);
getApplicationContext()
cannot resolve method getApplicationContect()
Responder

29.
Eduardo Gutirrez24 enero, 2015 10:04

Buenas esta parte esta incorrecta no ? Me da error:


public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLA_CONTACTOS);
onCreate(db);
}
Ya que el drop table tiene que ir seguido del nombre de la tabla solo.... despues ya la
volvera a crear en el oncreate...

drop table contactos en el on upgrade


Estoy en lo cierto ?
Gracias
Responder
30.
Annimo16 febrero, 2015 20:47

Hola estoy en las mismas tengo una duda deseo hacer dos botones para consultar al
cursor donde estan cargados todos los datos de la tablay poderlos cargar en 3
textview uno int y dos strtring. La idea es de un boton adelante y otro atras para
navergar sobre los registros cargados en el cursor. De antemano gracias a quien me
pueda colaborar.
Responder

31.
joz17 septiembre, 2015 18:33

eres un crack viejo nose si me vaya a funcionar pero al menos me aclaraste muchas
dudas sobre base de datos gracias
Responder

32.
christian jordy mamani sucasaire16 enero, 2016 01:18

Holas tengo una duda cuando guardo datos del sqlite en el cel, se guarda en el
archivo DATA pero no puedo acceder a ella...hay alguna solucin para extraer ese
dato en un archivo o guardarlo en la memoria externa?
Responder
33.
Annimo16 febrero, 2016 23:33

Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieseis algn consejo o algn link.
Responder
34.
Annimo17 febrero, 2016 02:04

Hola, primero que todo, tengo que decir que soy nuevo en esto y estoy probando a
hacer una app.
Mi problema es que al inicio de la misma, me gustara que apareciese un pequeo
formulario que preguntase nombre, edad y peso. Segn el usuario introduzca los
datos, que estos se almacenen en su memoria interna y al abrir otro da la app, no
tener que introducirlos de nuevo, sino que se conecte directamente a otro
men/pantalla con los datos guardados.
Me gustara que me dieseis algn consejo o algn link.
Responder

Bases de Datos Android - Como crear una Base de Datos SQLite en Android

Crear Base de Datos.


SQLite es un motor de bases de datos muy popular en la actualidad por ofrecer
caractersticas tan interesantes como su pequeo tamao, su simplicidad en la
configuracin, ser transaccional y por supuesto... ser de cdigo libre!. Android incorpora
todas las herramientas necesarias para la creacin y gestin de bases de datos SQLite, y
entre ellas, una completa API para llevar a cabo de manera sencilla todas las tareas que
necesitaremos en nuestra aplicacion, como insertar datos, leer datos y filtrar datos....
En Android, la forma tpica para crear, actualizar, y conectar con una base de datos SQLite
es a travs de una clase auxiliar llamada SQLiteOpenHelper, esta clase tiene tan slo un
constructor, que normalmente no necesitaremos sobrescribir, y dos mtodos abstractos,
onCreate() y onUpgrade(), que deberemos personalizar con el cdigo necesario para crear
nuestra base de datos y para actualizar su estructura si fuese necesario.
Como ejemplo, voy a utilizar una aplicacion que hice hace unos meses ReForest (esta en
GooglePlay), esta BD contiene una sola tabla llamada lugares que contiene varios campos.
Esta es la Clase BaseDeDatos que use, esta es una clase tipica, no necesitas mas para crear
una BD.

Arriba ves una clase tipica para crear y gestionar una Base de datos, como ves no tiene
mucho cogigo, costa de 3 partes claramente identificadas, una primera parte en la que
definen las variables de tipo texto (String) que contendran las sentencias de SQL para crear
las Tablas y/o actualizarlas, el metodo OnCreate de la clase, que es el encargado de crear la
tabla, y por ultimo el metodo OnUpdate, que normalmente estara vacio, es el que
utilizamos en el caso de necesitar crear alguna tabla nueva o algun campo nuevo, esto se
utiliza si por ejemplo actualizamos nuestra aplicacion porque hemos aadido nuevas
funcionalidades que requieren mas campos en nuestra BD.
Una sentencia SQL. El lenguaje de consulta estructurado o SQL (por sus siglas en ingls
structured query language) es un lenguaje declarativo de acceso a bases de datos
relacionales que permite especificar diversos tipos de operaciones en ellas. Una de sus
caractersticas es el manejo del lgebra y el clculo relacional que permiten efectuar
consultas con el fin de recuperar de forma sencilla informacin de inters de bases de
datos, as como hacer cambios en ella.

Supongo que no tendras mucha idea es esto no te preocupes! voy a explicar por encima las
sentencias que vamos a usar. Una Base de Datos es como un contenedor, dentro de este
puedes crear tantas tablas como quieras, las tablas son como organizadores, cuando
tenemos muchos campos y una aplicacion compleja, lo normal es crear varias tablas, no
esta bien crear todos los campos en una sola tabla (como poder se puede) pero no seria
correcto por motivos de organizacion y sobre todo de rendimiento (a la hora de hacer las
consultas cuanto mas grande es la tabla, es decir cuanto mas campos, mas tiempo se
necesita para consultar los datos), en nuestro caso si es correcto crear una tabla, porque es
una aplicacion sencilla con pocos campos. El ultimo componente de una BD son los
campos, los campos son las columnas que tendra la tabla, y las filas seran los registros que
contenga.

Una tabla debe contener siempre un campo llamado ID en el caso de Android este campo se
llamara _id asi en minusculas este campo es de tipo numerico y se auto-genera e
incrementa con cada registro que aadimos a la BD, piensa que una base de datos es como
un excel, contiene tantas columnas como campos, y tantas filas como registros y es
necesario que cada fila se numere de forma unica, el campo _id es como el DNI de cada
fila, de esta forma podremos encontrar la fila cuando la necesitemos, y en el caso de que
creemos otras tablas ese campo _id sera en que necesitemos para relacionar cada tabla entre
si, por eso este campo es muy importante. Voy a ponerte un ejemplo para que lo veas de
forma mas grafica una tabla con datos y lo comprendas mejor:

La tabla de arriba, contiene 4 campos (ID, Title, Type, Comment) y tiene 20 registros, fijate
que el campo ID es el numerico y unico. Cuando consultemos una Base de Datos, en
concreto esta tabla, pondremos un elemento llamado cursor en la primera FILA y nosotros
medienate otras instrucciones seremos capaces de desplazarnos por ella, leer los registros,
etc... mas adelante en proximas lecciones ya veremos como.
Ahora que a grandes rasgos ya sabes como es una Base de Datos vamos a ver el tema de las
sentencias SQL en concreto comencemos con la de crear una Base de datos, fijate en cada
parentesis y en cada coma TODO es necesario!!

Estas sentencias son MUY sensibles tienes que respetar su sintasis, ahora vamos a analizar
la sentencia:
String sqlCreate2 = "sentencia de SQL". Aqui se crea una variable de tipo texto que se
llama sqlCreate2, entre las comillas se pone la sentencia de SQL, estas comillas no forman
parte de la sentencia, son de la propia instruccion de Android para crear la variable de tipo

texto.
CREATE TABLE lugares (campos a crear);. Aqui definimos el tipo de sentencia SQL,
estamos diciendo que vamos a crear una tabla llamada lugares y entre los parentesis van los
campos que contendra dicha tabla acabamos con el ; que es propio de la instruccion de
Android, como hemos visto hasta aquicada instruccion de Android acaba con el ;.
_id INTEGER PRIMARY KEY AUTOINCREMENT, nombre TEXT Aqui creamos el
campo principal _id y el campo nombre que es de tipo texto, fijate con detalle que se pone
siempre el nombre del campo seguido del tipo de dato y entre ellos se separan mediante
'comas' esto debe ser asi, lo normal es poner comas de mas o de menos, esto es un error
muy habitual, presta atencion a las comas y parentesis!!.
Cuando llamemos a nuestra base de datos desde nuestro programa principal, este ira a la
clase que hallamos creado con anterioidad que extiende de la clase SQLiteOpenHelper y
ejecurara el codigo que se encuentra en el mtodo onCreate() y cuando he dicho por
primera vez, lo digo porque este codigo se ejecutara una unica vez, solo para crear la BD,
una vez creada, este metodo no se volera a ejecutar NUNCA.
Las tareas tpicas que deben hacerse en este mtodo sern: la creacin de todas las tablas
necesarias y la insercin de los datos iniciales si son necesarios, en este caso, slo creo la
tabla. Para la creacin de la tabla uso la sentencia SQL que comente antes y la ejecutaremos
contra la base de datos utilizando el mtodo ms sencillo de los disponibles en la API de
SQLite proporcionada por Android, llamado execSQL(sentencia SQL). Este mtodo se
limita a ejecutar directamente el cdigo SQL que le pasemos como parmetro.

La proxima leccion seguiremos analizando todo esto, espero que la cosa se valla
entendiendo, no te agobies, poco a poco iras encajando el puzzle, recuerda que puedes
opinar y/o sujerir mejoras en el FORO, por favor no te cortes, opina, mi objetivo es que
puedas aprender a programar, y no me bienen mal opiniones constructivas para mejorar la
web. Saludos!

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DBAdapter {
private final static int DB_VERSION = 1;
private final static String DB_NAME = "nombreDB";
private final static String TB_NAME = "nombreTabla";
private class Columns implements BaseColumns {
public final static String ID = "_id";
public final static String CAMPO1 = "campo1";
public final static String CAMPO2 = "campo2";
public final static String CAMPO3 = "campo3";
// ...
}
private final static String CR_TABLE = "create table if not exists "
+ TB_NAME + "(" + Columns.ID
+ " integer autoincrement primary key, " + Columns.CAMPO1
+ " text not null, " + Columns.CAMPO2 + " text, " +
Columns.CAMPO3
+ " integer)";
private DBHelper dbHelper;
public DBAdapter(Context context) {
dbHelper = new DBHelper(context);
}
private class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CR_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int
newVersion) {
db.execSQL("drop table if exists " + TB_NAME);
onCreate(db);
}
}
}

Anda mungkin juga menyukai