Bienvenidos sean a este post, hoy veremos algunas operaciones que podemos aplicar sobre nuestra base de datos y para ello volveremos a nuestra app MisLugares, para nuestra primera operacion veremos como hacer una consulta sobre la base de datos y para ello iremos a la clase Lugares y modificaremos el metodo elemento() con el siguiente codigo:
public static Lugar elemento(int id){
Lugar lugar = null;
SQLiteDatabase db = lugaresDB.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * from lugares WHERE _id ="
+ id,null);
if(cursor.moveToNext()){
lugar = new Lugar();
lugar.setNombre(cursor.getString(1));
lugar.setDireccion(cursor.getString(2));
lugar.setPosicion(new GeoPunto(cursor.getDouble(3),
cursor.getDouble(4)));
lugar.setTipo(TipoLugar.values()[cursor.getInt(5)]);
lugar.setFoto(cursor.getString(6));
lugar.setTelefono(cursor.getInt(7));
lugar.setUrl(cursor.getString(8));
lugar.setComentario(cursor.getString(9));
lugar.setFecha(cursor.getLong(10));
lugar.setValoracion(cursor.getFloat(11));
}
cursor.close();
db.close();
return lugar;
}
Esta modificacion es bien simple, primero crearemos un objeto llamado lugar de tipo Lugar, luego crearemos un objeto llamado db del tipo SQLiteDatabase y a su vez la haremos leible por medio de getReadableDatabase(), despues crearemos un cursor y le enviaremos por medio de un rawQuery un query donde seleccionaremos todos los datos almacenados del id informado en los atributos, si cursor es distinto de nada procedera a buscar cada uno de los elementos por medio de moveToNext y si esta condicion se cumple procedera a setear cada uno de los elementos en Lugar por medio de cursor y cada una de las posiciones de la base, una vez agregados los valores saldremos del condicional, cerraremos el cursor y la conexion de la base para devolver todo los valores almacenados en lugar, si lo compilan y ejecutan en un emulador al presionar sobre cualquiera de los lugares nos traera todos los datos del lugar, nuestra siguiente operacion sera la modificacion de un lugar, y para ello agregaremos el metodo actualizaLugar a nuestra clase Lugares, este es el metodo que deberan agregar:
public static void actualizarLugar(int id, Lugar lugar){
SQLiteDatabase db = lugaresDB.getWritableDatabase();
db.execSQL("UPDATE lugares set nombre = '" + lugar.getNombre()
+ "',direccion='" + lugar.getDireccion()
+ "',longitud=" + lugar.getPosicion().getLongitud()
+ ",latitud=" + lugar.getPosicion().getLatitud()
+ ",tipo=" + lugar.getTipo().ordinal()
+ ",foto='" + lugar.getFoto()
+ "',telefono=" + lugar .getTelefono()
+ ",url='" + lugar.getUrl()
+ "',comentario='" + lugar.getComentario()
+ "',fecha=" + lugar.getFecha()
+ ",valoracion=" + lugar.getValoracion()
+ " WHERE _id=" + id);
db.close();
}
Este metodo es sencillo, en el cual recibiremos dos datos: uno es el id del lugar y otro el lugar en si, despues crearemos una conexion a la base y por medio del metodo getWritableDatabase() podremos escribir en ella, despues por medio de execSQL haremos una actualizacion de la entrada informada en id y actualizaremos todos los campos, luego cerraremos la conexion a la base, despues de estas modificaciones debemos ir a VistaLugar y en el metodo onCreate() mueve la siguiente linea:
lugar = Lugares.elemento((int) id);
Y esta la pondremos en la primer linea del metodo actualizarVistas(), quedando el metodo de la siguiente forma:
public void actualizarVistas(){
lugar = Lugares.elemento((int) id);
TextView nombre = (TextView) findViewById(R.id.nombre);
nombre.setText(lugar.getNombre());
ImageView logo_tipo = (ImageView) findViewById(R.id.logo_tipo);
logo_tipo.setImageResource(lugar.getTipo().getRecurso());
TextView tipo = (TextView) findViewById(R.id.tipo);
tipo.setText(lugar.getTipo().getTexto());
TextView direccion = (TextView) findViewById(R.id.direccion);
direccion.setText(lugar.getDireccion());
TextView telefono = (TextView) findViewById(R.id.telefono);
telefono.setText(Integer.toString(lugar.getTelefono()));
TextView url = (TextView) findViewById(R.id.url);
url.setText(lugar.getUrl());
TextView comentario = (TextView) findViewById(R.id.comentario);
comentario.setText(lugar.getComentario());
TextView fecha = (TextView) findViewById(R.id.fecha);
fecha.setText(DateFormat.getDateInstance().format(
new Date(lugar.getFecha())));
TextView hora = (TextView) findViewById(R.id.hora);
hora.setText(DateFormat.getTimeInstance().format(
new Date(lugar.getFecha())));
RatingBar valoracion=(RatingBar) findViewById(R.id.valoracion);
valoracion.setRating(lugar.getValoracion());
valoracion.setOnRatingBarChangeListener(
new RatingBar.OnRatingBarChangeListener() {
@Override
public void onRatingChanged(RatingBar ratingBar,
float valor, boolean fromUser) {
lugar.setValoracion(valor);
}
}
);
ponerFoto(imageview, lugar.getFoto());
}
En la clase VistaLugar iremos al metodo actualizarVistas() y buscaremos el metodo onRatingChanged() donde agregaremos la siguiente linea:
Lugares.actualizarLugar((int) id, lugar);
Quedando el metodo de la siguiente forma:
@Override
public void onRatingChanged(RatingBar ratingBar,
float valor, boolean fromUser) {
lugar.setValoracion(valor);
Lugares.actualizarLugar((int) id, lugar);
}
Esta linea la agregaremos en el metodo onActivityResult(), a continuacion copiare el bloque de este metodo y resaltare las lineas que agregamos:
public void onActivityResult(int requestCode, int resultCode,
Intent data){
if (requestCode==1234){
actualizarVistas();
findViewById(R.id.scrollView1).invalidate();
} else if (requestCode == RESULTADO_FOTO
&& resultCode == Activity.RESULT_OK
&& lugar!=null && uriFoto!=null ){
lugar.setFoto(uriFoto.toString());
Lugares.actualizarLugar((int) id, lugar); // Nueva linea
ponerFoto(imageview,lugar.getFoto());
} else if(requestCode == RESULTADO_GALERIA
&& resultCode == Activity.RESULT_OK){
lugar.setFoto(data.getDataString());
Lugares.actualizarLugar((int) id, lugar); // Nueva linea
ponerFoto(imageview, lugar.getFoto());
}
}
En ambos casos va a primero setear el valor a foto, luego llamaremos al metodo actualizarLugar para que guarde el nuevo valor de foto y luego la pondremos por medio del metodo ponerFoto(), nuestra siguiente modificacion sera en el metodo eliminarFoto(), para ello deben ir al metodo onClick donde agregaremos la linea antes descripta, debera quedar de la siguiente manera:
@Override
public void onClick(DialogInterface dialog,
int cualBoton) {
lugar.setFoto(null);
Lugares.actualizarLugar((int) id, lugar);
ponerFoto(imageview,null);
}
Y por ultimo debemos agregarlo en el metodo onOptionsItemSelected() de la clase EdicionLugar, esta debe estar dentro del metodo guardar() antes del finish() como veremos a continuacion:
public void guardar(){
lugar.setNombre(nombre.getText().toString());
lugar.setTipo(TipoLugar.values()[tipo.getSelectedItemPosition()]);
lugar.setDireccion(direccion.getText().toString());
lugar.setTelefono(Integer.parseInt(telefono.getText().toString()));
lugar.setUrl(url.getText().toString());
lugar.setComentario(comentario.getText().toString());
Lugares.actualizarLugar((int)id, lugar);
finish();
}
Con esto podriamos probar todas nuestras modificaciones como se ve en el siguiente video
En este video podemos ver como nos trae la consulta, modificamos el ranking de las estrellas, el texto y agregamos una foto, salimos de la app y volvimos a entrar para ver como funciono correctamente, vamos a ver nuestra ultima modificacion que es para agregar nuevos lugares.
Para ello iremos a la clase Lugares y reemplazaremos el codigo actual de nuevo() por el siguiente:
public static int nuevo(){
int id = -1;
Lugar lugar = new Lugar();
SQLiteDatabase db = lugaresDB.getWritableDatabase();
db.execSQL("INSERT INTO lugares (longitud,latitud,tipo,fecha) values ("
+ lugar.getPosicion().getLongitud() +","
+ lugar.getPosicion().getLatitud() + ","
+ lugar.getTipo().ordinal() + ","
+ lugar.getFecha() + ")");
Cursor c = db.rawQuery("SELECT _id from lugares WHERE fecha ="
+ lugar.getFecha(), null );
if (c.moveToNext())
id = c.getInt(0);
c.close();
db.close();
return id;
}
En este primero crearemos la variable id con el valor -1 para ante algun error devuelve ese valor, luego tendremos un objeto lugar de tipo Lugar para crear la conexion a nuestra base y permitir que se pueda escribir en ella, despues vendra un comando donde ingresaremos algunos valores para crear una nueva entrada, despues crearemos una consulta para obtener el valor de _id de la nueva entrada y finalmente por medio del condicional si todo hasta aqui funciono correctamente lo asignaremos a id, para finalmente cerrar a nuestro cursor y nuestra conexion y devolver el valor asignado a id. Nuestra siguiente modificacion la haremos al archivo res/menu/menu_main.xml para agregar el siguiente item:
<item android:title="nuevo"
android:id="@+id/accion_nuevo"
android:icon="@android:drawable/ic_menu_add"
android:orderInCategory="80"
android:showAsAction="ifRoom" />
Este solo sera un item para la pantalla donde nos permitira utilizar la accion de agregar una nuevo lugar, nuestra siguiente modificacion sera en MainActivity donde iremos al metodo onOptionsItemSelected() para agregar el siguiente codigo:
if (id == R.id.accion_nuevo){
long id2 = Lugares.nuevo();
Intent i = new Intent(this, EdicionLugar.class);
i.putExtras("nuevo",true);
i.putExtras("id",id2);
startActivity(i);
return true;
}
Con esto podremos llamar a la actividad necesaria para poder agregar nuestro nuevo valor, en este caso enviaremos un valor llamado nuevo y otro id con id2 pero nos servira para mas adelante, luego inicia la actividad y por ultimo devuelve true. Con estas modificaciones realizadas podemos probar de nuevo la app como se ve en el siguiente video
Como pueden ver en el video ahora tambien poseeremos la posibilidad de agregar nuevos lugares a nuestra app, si observan ya habia agregado uno de prueba pero todavia no logramos que se actualice automaticamente despues de creado, aunque eso lo veremos un poco mas adelante.
En resumen, hoy hemos visto como hacer nuestras consultas, como realizar modificaciones en nuestros lugares y finalmente como dar de alta un nuevo lugar, todo por medio de nuestras base de datos, esto nos abre un gran campo a la hora de almacenar y mostrar informacion para los usuarios, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50