Aprende Android

Vaya al Contenido

Menu Principal

Almacenamiento de datos (2ª parte)

Almacenando datos

Vamos a crear y editar tareas con SQLite

Para crear una tarea es necesario insertar un registro.
Cuando este registro aparece en la lista de tareas en el ReminderListActivity, se puede, tras presionar un segundo sobre ella, eliminarla. O modificarla cuando se hace clic sobre la misma.

Insertar una tarea


Vamos a realizar los siguientes pasos:

  • Declarar las variables locales necesarias.

  • Construir el botón “Guardar”.

  • Recuperar los valores de EditText views.

  • Interactuar con la clase ReinderDbAdapter.

  • Abrir y cerrar la base de datos.


Para crear una tarea, se lleva a cabo en la clase ReminderEditActivity, siendo necesario crear una variable de la clase RemindersDbAdapter con el método onCreate(). Después de creada la instancia se abre la base de datos con una llamada con el método Open() en el método onResume() en RemindersDbAdapter.

Escribe el siguiente código en la clase ReminderEditActivity:

           
mDbHelper = new RemindersDbAdapter(this);

El archivo “ReminderEditActivity.class” te tiene que quedar así:

package es.greval.taskReminder;

import android.app.Activity;
import android.os.Bundle;

public class ReminderEditActivity extends Activity{

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);

   mDbHelper = new RemindersDbAdapter(this);

                       setContentView(R.layout.reminder_edit);
   }
}

En este punto tenemos una referencia a la RemindersDbAdapter que nos permite llamar a la clase RemindersDbAdapter para crear una tarea.

Para agregar la tarea es necesario el título, descripción, fecha de recordatorio y la hora.

Para acceder al título y la descripción, es necesario agregar tres variables a ReminderEditActivity. Dos de ellas son variables del tipo EditText que hacen referencia a los valores e la EditText en el diseño de la ReminderEditActivity. También hay un botón (Guardar), para hacer clic y guardar la tarea en la base de datos.

Para ello, escribe en la parte superior del archivo “ReminderEditActivity.class” el siguiente código:

private EditText  mTitleText;
private EditText mBodyText;
private Button mConfirmButton;


Es necesario crear una instancia que llame al método onCreate():

mTitleText = (EditText) findViewById(R.id.title);
mBodyText = (EditText) findViewById(R.id.cuerpo);
mConfirmButton = (Button) findViewById(R.id.confirm);


Para la fecha y la hora, existe el objeto Calendar, que se rellena a partir de DatePicker y TimePicker, respectivamente, por lo que no es necesario crear nada para estos valores. No obstante, las instancias son:

mCalendar = Calendar.getInstance();
mDateButton = (Button) findViewById(R.id.reminder_date);
mTimeButton = (Button) findViewById(R.id.reminder_time);


Ahora nos queda ofrecer la posibilidad de guardar la tarea después de que el usuario escriba los valores en los campos EditText del título y la descripción, pulsando el botón “Guardar”. Para ello, es necesario escribir el siguiente código en el método “registerButtonListenersAndSetDefaultText()”:

1 mConfirmButton.setOnClickListener(new View.OnClickListener() {
2          public void onClick(View view) {
3                      saveState();
4                      setResult(RESULT_OK);
5                      Toast.makeText(ReminderEditActivity.this,
6                      getString(R.string.task_saved_message),
7                                 Toast.LENGTH_SHORT).show();
8                      finish();
         }
 });


En la línea 3 se llama al método “saveState()”.
En la 4 se establece el resultado de la clase ReminderEditActivity.
Entre la línea 5 y la 7 se crea un mensaje haciendo saber al usuario que la tarea ha sido guardada con éxito.
En la 8 se pone el método finish(), que cierra ReminderEditActivity.

Creando el método que guarda la tarea

Ahora vamos a crear el método “saveState()” en ReminderEditActivity, que nos va a guardar los datos de la tarea creada:

1  private void saveState() {
2          String title =  mTitleText.getText().toString();
3          String body = mBodyText.getText().toString();
4
5          SimpleDateFormat dateTimeFormat = new
6                      SimpleDateFormat(DATE_TIME_FORMAT);
7          String reminderDateTime=
8                      dateTimeFormat.format(mCalendar.getTime());
9
10        long id = mDbHelper.createReminder(title, body, reminderDateTime);
11 }


Las líneas 2 y 3 recuperan el texto de los EditText views.
Las líneas 5 y 6 definen un SimpleDateFormat que va a utilizar para almacenar la fecha y hora dentro de la base de datos SQLite. Para ello es necesario crear en la parte superior del archivo de la clase el siguiente código:

public static final String DATE_TIME_FORMAT = “yyyy-MM-dd kk:mm:ss”;

Esto define un formato de fecha y hora para almacenar en la base de datos SQLite.
Las líneas 7 y 8 cogen la fecha y hora y los coloca en una variable local.
La 10 guarda la tarea.

¿Cómo queda el archivo “RemindersDbAdapter.class” completo?

Vamos a ver cómo quedaría el archivo completo, por si te hubieras o te hubiera hecho perder entre tanta línea de código:

1  package es.greval.taskReminder;
2
3  import android.content.ContentValues;
4  import android.content.Context;
5  import android.database.Cursor;
6  import android.database.SQLException;
7  import android.database.sqlite.SQLiteDatabase;
8  import android.database.sqlite.SQLiteOpenHelper;
9
10 public class RemindersDbAdapter {
11    private static final String DATABASE_NAME = "data";
12    private static final String DATABASE_TABLE = "reminders";
13    private static final int DATABASE_VERSION = 1;
14    
15    public static final String KEY_TITLE = "title";
16    public static final String KEY_BODY = "body";
17    public static final String KEY_DATE_TIME = "reminder_date_time";
18    public static final String KEY_ROWID = "_id";
19    
20    private DatabaseHelper mDbHelper;
21    private SQLiteDatabase mDb;
22    
23    private static final String DATABASE_CREATE =
24          "create table" + DATABASE_TABLE + " ("
25          + KEY_ROWID + " integer primary key autoincrement, "
26          + KEY_TITLE + " text not null, "
27          + KEY_BODY + " text not null, "
28          + KEY_DATE_TIME + " text not null);";
29    
30    private final Context mCtx;
31    
32    public RemindersDbAdapter(Context ctx) {
33          this.mCtx = ctx;
34    }
35    
36    public RemindersDbAdapter open() throws SQLException {
37          mDbHelper = new DatabaseHelper(mCtx);
38          mDb = mDbHelper.getWritableDatabase();
39          return this;
40    }
41    public void close() {
42          mDbHelper.close();
43    }
44    
45    public long createReminder(String title, String body,
String reminderDateTime) {
47          ContentValues initialValues = new ContentValues();
48          initialValues.put(KEY_TITLE, title);
49          initialValues.put(KEY_BODY, body);
50          initialValues.put(KEY_DATE_TIME, reminderDateTime);
51          
52          return mDb.insert(DATABASE_TABLE, null, initialValues);
53    }
54    
55    public boolean deleteReminder(long rowId) {
56          return
57                mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId,
null) > 0;
59    }
60    
61    public Cursor ferchAllReminders() {
62          return mDb.query(DATABASE_TABLE, new String[]{KEY_ROWID,
KEY_TITLE, KEY_BODY,
                       KEY_DATE_TIME}, null, null, null, null, null);
65    }
66    
67    public Cursor ferchReminder(long rowId) throws SQLException {
68          Cursor mCursor = mDb.query(true, DATABASE_TABLE, new String []
69               {KEY_ROWID, KEY_TITLE, KEY_BODY, KEY_DATE_TIME},
KEY_ROWID +
71               "=" + rowId, null, null, null, null, null);
72          if (mCursor != null) {
73                mCursor.moveToFirst();
74          }
75          return mCursor;
76    }
77    
78    public boolean updateReminder(long rowId, String title, String body,
String reminderDateTime) {
80          ContentValues args = new ContentValues();
81          args.put(KEY_TITLE, title);
82          args.put(KEY_BODY, body);
83          args.put(KEY_DATE_TIME, reminderDateTime);
84          
85          return
86                mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" +
rowId, null) > 0;
88    }
89    
90    private static class DatabaseHelper extends SQLiteOpenHelper {
91          DatabaseHelper(Context context) {
92                super(context,DATABASE_NAME,null,DATABASE_VERSION);
93          }
94
95          @Override
96          public void onCreate(SQLiteDatabase db) {
97                db.execSQL(DATABASE_CREATE);
98          }
99
100         @Override
101         public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {            
103         }
104   }     
105 }

Vamos a explicar un poquitín este código:

En la fila 45-46, se crea el método createReminder(). Por debajo de esta declaración, está el objeto ContentValues que se utiliza para definir los valores delas diferentes columnas en la fila de la base que se inserta.
En la 52 la llamada a insert() se realiza para insertar la fila en la base de datos. Este método devuelve el identificador único de la fila que se acaba de insertar en la base de datos. En el ReminderEditActivity se establece una variable local que se utiliza para ayudar a la clase AlarmManager (la veremos en otro capítulo) a averiguar qué tarea es la con la que trabajará. El uso del método Insert y sus parámetros los detallaremos en otra sección más adelante.
En la línea 55 se define el método deleteReminder(). Acepta el parámetro de la fila a eliminar (rowId).
En la 57-58 se utiliza el rowId, haciendo una llamada al método delete() de la base de datos de SQLite para eliminar una tarea desde la propia base de datos. (Más adelante veremos el uso y parámetros del método delete())
En la línea 61, se define el método fetchAllReminders(), que utiliza el método query() sobre la base de datos de SQLite para encontrar todos los avisos en el sistema (se explicará más adelante).
En la 67 se define el método fetchReminder(), que acepta un parámetro (el Id de la fila de la tarea en la base de datos).
En la 73 el objeto Cursor puede contener muchas filas; sin embargo, la posición inicial no está en el primer registro, El moveToFirst() le dice al cursor que vaya al primer registro en el conjunto de resultados. Este método sólo se llama si el cursor no es nulo. La razón de que el cursor no está colocado en el primer registro es porque se trata de un conjunto de resultados. Antes de empezar a trabajar con el registro, debe desplazarse a él.
En la línea 78-79 se defina la updateReminder() que utiliza el método Update(). El método Update() se encarga de actualizar una tarea existente con nueva información.
En la 80 se crea el objeto ContentValues. Este objeto almacena los diferentes valores necesarios para recibir información actualizada de la base de datos SQLite.
En la 86-87 se actualizan los registros de la base de datos con los nuevos valores que han sido proporcionados por el usuario.

Vamos a explicar la operación insertar

Al insertar introducimos un valor en la base de datos. El método insert() acepta los siguientes parámetros:

table: El nombre de la tabla para insertar los datos. Usamos el valor de la constante DATABASE_TABLE.
nullColumnHack: SQL no permite insertar una fila vacía por completo, por lo que si el parámetro de ContentValues  (next parameter) está vacío, a esta columna se le asigna un valor NULL.
values: este parámetro define los valores iniciales, definido como un objeto ContentValues. Se proporciona la variable local initialValues coo el valor de este parámetro.

Explicación de la operación consulta

La operación de consulta es equivalente a lectura de los datos de la base de datos. El método query() es el responsable de proporcionar un conjunto de resultados basándose en una lista de criterios que el usuario proporciona. Este método de consulta acepta los siguientes parámetros:

distinct: Es para que cada registro sea único. Se pone el valor en true.
table: El nombre de la tabla de la base de datos hacia la que se dirige la consulta.
columns: Es la lista de columnas que ofrece la consulta. Si se quiere que devuelva todas las columnas, se pone el valor en null.
selection: Si se pone el valor null, se relacionan todas las tareas. Para realizar un filtro, se utiliza la palabra WHERE en el lenguaje SQL.
selectionArgs: Son argumentos para la selección, para lo que se incluye el símbolo de interrogación (?). Si no se necesita se pone null.
groupBy: Sirve para agrupar las tareas, y se utiliza las palabras en lenguaje SQL “GROUP BY. Si no se quieren agrupar, se pone null.
having: Este es un filtro que se utiliza para describir los grupos de filas.
orderBy: Para ordenar las filas, con el formato de SQL “ORDER BY”.
limit: Limita el número de filas devueltas por la consulta mediante la utilización de la cláusula LIMIT.

Explicación de la operación “actualización” (update)

Se utiliza el método update () para actualizar los registros de la base de datos. Para ello, lo único que realiza es reemplazar en la celda de destino dentro de la fila o filas a actualizar, los datos.
Los parámetros de actualización son:

table: La tabla a actualizar, siendo el valor proporcionado por la constante DATABASE_TABLE.
values: El objeto ContentValues contiene los campos a actualizar.
whereClause: La cláusula WHERE restringe las filas que deben actualizarse. Se informa a la base de datos que actualice el registro cuyo identificador es igua a ROWID, proporcionando el valor de la cadena: KEY_ROWID + “=” + rowId.
whereArgs: Son argumentos que se le indican a la cláusula WHERE. Si no es necesaria se se pone un valor null.

__________________________________________
Para cualquier duda que tengas sobre este ejemplo, cómprate el libro del que estoy sacando los apuntes. Lo puedes encontrar en internet en esta dirección:

http://eu.dummies.com/store/product/Android-Application-Development-For-Dummies.productCd-047077018X.html

Regreso al contenido | Regreso al menu principal