Tutorial Android paso a paso III: Desarrollo de la aplicación Notepad

febrero 23, 2010

En este tercer y último post del tutorial, vamos a practicar el ciclo de vida de la aplicación, y como guardar y recuperar el estado de la aplicación.

Puedes ver los anteriores artículos:
Tutorial Android paso a paso I: Desarrollo de la aplicación Notepad
Tutorial Android paso a paso II: Desarrollo de la aplicación Notepad

Objetivos:
• Conocer los eventos del ciclo de vida de la aplicación.
• Tecnicas para mantener el estado de la aplicación.

Paso 1

La aplicación actual contiene algunos problemas. Para solucionarlo, vamos a mover la funcionalidad de edición de notas a la clase NoteEdit.

1. Eliminar el siguiente código de la clase NoteEdit, que obtiene los datos de la nota a través del Bundle. Vamos a pasar a utilizar la clase DBHelper para obtener los datos directamente de la base de datos.

1
2
3
4
5
Bundle extras = getIntent().getExtras();String title = extras.getString(NotesDbAdapter.KEY_TITLE);
String body = extras.getString(NotesDbAdapter.KEY_BODY);
mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);

2. Además, eliminamos la asignación de los datos a la interfaz de usuario

1
2
3
4
5
6
if (title != null) {
    mTitleText.setText(title);
}
if (body != null) {
    mBodyText.setText(body);
}

Paso 2

Conectamos la clase NoteEdit con la base de datos.

1. Creamos un nuevo atributo:

1
private NotesDbAdapter mDbHelper;

2. Conectamos con la base de datos en el constructor, justo después de llamar al constructor padre:

1
2
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();

Paso 3

Pasamos a comprobar el estado de la variable savedInstanceState. Esto sirve para comprobar si tenemos datos guardados en el Bundle, que debemos recuperar (Esto ocurre si la actividad pierde el foco y después se recupera).

1. Reeplazar el siguiente código:

1
2
3
4
5
mRowId = null;
Bundle extras = getIntent().getExtras();
if (extras != null) {
    mRowId = extras.getLong(NotesDbAdapter.KEY_ROWID);
}

Por este otro

1
2
3
4
5
mRowId = savedInstanceState != null ? savedInstanceState.getLong(NotesDbAdapter.KEY_ROWID) : null;
if (mRowId == null) {
    Bundle extras = getIntent().getExtras();
    mRowId = extras != null ? extras.getLong(NotesDbAdapter.KEY_ROWID) : null;
}

Paso 4

Necesitamos completar los campos con los datos de la nota. Llamamos al método populateFields() que completaremos más adelante. Insertarlo justo antes de confirmButton.setOnClickListener():

1
populateFields();

Paso 5

En esta actividad ya no es necesario devolver ningún tipo de datos, ya que vamos a guardar los datos directamente en esta actividad, por lo que es posible simplificar el método onClick() considerablemente:

1
2
3
4
public void onClick(View view) {
    setResult(RESULT_OK);
    finish();
}

Más adelante veremos como guardar los datos.

Paso 6

Definimos el método populateFields():

1
2
3
4
5
6
7
8
private void populateFields() {
    if (mRowId != null) {
        Cursor note = mDbHelper.fetchNote(mRowId);
        startManagingCursor(note);
        mTitleText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_TITLE)));
        mBodyText.setText(note.getString(note.getColumnIndexOrThrow(NotesDbAdapter.KEY_BODY)));
    }
}

Paso 7

Implementamos los métodos que gestionan el ciclo de vida de Android. Estos métodos nos permiten guardar y recuperar el estado de la actividad en caso de que esta se cierre o pase a un segundo plano (al recibir una llamada, por ejemplo):

1. onSaveInstanceState(): es llamada por Android cuando la actividad va a ser cerrada. Esto significa que aquí se debe guardar toda la información necesaria para restaurar la actividad en su estado anterior. Podemos pensar que es el método contrario a onCreate(), de hecho el Bundle que construimos en este método, es el que será pasado al método onCreate().

1
2
3
4
5
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putLong(NotesDbAdapter.KEY_ROWID, mRowId);
}

2. onPause(): es llamada cuando la actividad va a terminar (con finish()) o pasar a un segundo plano (con una llamada de teléfono).

1
2
3
4
5
@Override
protected void onPause() {
    super.onPause();
    saveState();
}

3. onResume(): es llamada al reactivar la actividad. Completamos los campos:

1
2
3
4
5
@Override
protected void onResume() {
    super.onResume();
    populateFields();
}

Paso 8

Para terminar de completar la clase NoteEdit, ya solo nos queda guardar los datos en la base de datos. Creamos el método saveState():

1
2
3
4
5
6
7
8
9
10
11
12
private void saveState() {
    String title = mTitleText.getText().toString();
    String body = mBodyText.getText().toString();
    if (mRowId == null) {
        long id = mDbHelper.createNote(title, body);
        if (id > 0) {
            mRowId = id;
        }
    } else {
        mDbHelper.updateNote(mRowId, title, body);
    }
}

Paso 9

Volvemos a la clase Notepadv3. En el método onActivityResult(), teníamos implementado todo lo necesario para recibir los datos de la actividad y guardarla en la base de datos. Como este proceso ya lo realizamos en la clase NoteEdit, solo es necesario que actualizemos la lista con los nuevos datos:

1
2
3
4
5
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);
    fillData();
}

Paso 10

Finalmente, es esta misma clase, al seleccionar un elemento de la lista, ya no es ncesario pasar todos los datos de la nota, únicamente el id, por lo que el método onListItemClick(), quedaría de la siguiete manera:

1
2
3
4
5
6
7
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    Intent i = new Intent(this, NoteEdit.class);
    i.putExtra(NotesDbAdapter.KEY_ROWID, id);
    startActivityForResult(i, ACTIVITY_EDIT);
}

Y con este último post hemos terminado el tutorial. Espero que os haya servido de ayuda y, como siempre, cualquier duda o pregunta en los comentarios.

Tags ; , , ,

11 comentarios

    Hugo Feb 19, 2011

    Todavia no lo leeo a detalle pero me parece muy bueno, EXCELENTE TRABAJO.

    Responder
    Yesid Mar 20, 2011

    Esta muy bueno el tutorial, y en el simulador seguro que funciona; pero para llevarlo a un celular como se hace?, en cualquier celular con android funciona? sin importar la version de android?.

    Muchas gracias

    Responder
    Rafa Abr 10, 2011

    Hola!
    Acabo de terminar el tutorial y está bastante bien, aunque estaría aun mejor si explicases absolutamente todo, es decir, creando un proyecto nuevo desde 0. Si te animas, te lo agradeceré enormemente.

    Un saludo.

    Responder
    Elkki Nov 09, 2011

    Buenas,

    Muy bueno el tutorial, de gran ayuda para gente que sabe algo de java pero que android se le escapa.

    Muchas gracias.

    Responder
    seba Nov 28, 2011

    gracias por el tutorial me sirvió mucho

    Responder
    darkx Ene 18, 2012

    como se despliega la alplicacion, ya sea en un emulador o en el telefono??

    Responder
    Vot Feb 07, 2012

    Increíble el tutorial. Muchas gracias.

    Responder
    Samaniegomx Mar 06, 2012

    Hola que tal una duda esta muy bueno tu tutorial lo acabo de terminar pero me sale el siguiente error.

    Unfortunately, com.android.demo.notepad1 has stopped.

    03-06 17:20:35.102: E/AndroidRuntime(605): FATAL EXCEPTION: main
    03-06 17:20:35.102: E/AndroidRuntime(605): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=null} to activity {com.android.demo.notepad1/com.android.demo.notepad1.Notepadv1}: java.lang.NullPointerException
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread.deliverResults(ActivityThread.java:2980)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3023)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread.access$1100(ActivityThread.java:123)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1177)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.os.Handler.dispatchMessage(Handler.java:99)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.os.Looper.loop(Looper.java:137)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread.main(ActivityThread.java:4424)
    03-06 17:20:35.102: E/AndroidRuntime(605): at java.lang.reflect.Method.invokeNative(Native Method)
    03-06 17:20:35.102: E/AndroidRuntime(605): at java.lang.reflect.Method.invoke(Method.java:511)
    03-06 17:20:35.102: E/AndroidRuntime(605): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
    03-06 17:20:35.102: E/AndroidRuntime(605): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
    03-06 17:20:35.102: E/AndroidRuntime(605): at dalvik.system.NativeStart.main(Native Method)
    03-06 17:20:35.102: E/AndroidRuntime(605): Caused by: java.lang.NullPointerException
    03-06 17:20:35.102: E/AndroidRuntime(605): at com.android.demo.notepad1.Notepadv1.onActivityResult(Notepadv1.java:120)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.Activity.dispatchActivityResult(Activity.java:4649)
    03-06 17:20:35.102: E/AndroidRuntime(605): at android.app.ActivityThread.deliverResults(ActivityThread.java:2976)

    Saludos muchas gracias.

    Responder
    Yo Jul 09, 2012

    Esta muy bueno. Estaria mejor si pones imagenes

    Responder
    Mati Ene 21, 2013

    Hola, un gusto. Desde ya que mil gracias por el tutorial, está muy bien hecho. Quería hacerte unas preguntas:

    ¿Cómo harías para que ademas de notas se puedan subir fotos (Capturadas por el mismo dispositivo, es decir, que lanze la camara y tome una foto, y la misma quede guardada debajo de las notas)?
    Y videos? (De la misma forma, capturadas por el dispositivo celular o tablet que la esté ejecutando)

    Estaría mejor si se pudieran ordenar las notas por un lado, las imagenes por otro y los videos por otro, que no parece complicado.

    Agradezco tu respuesta, realmente la necesito!
    Saludos!

    Mati.

    Responder
    Alejandra Mar 22, 2013

    Hola!!! tu tutorial me ha ayudado bastante, pero tengo una pregunta ¿las notas que haces con ésta aplicación se pueden visualizar en una computadora?

    De antemano, gracias.

    Responder

Escribe un comentario

Los comentarios son moderados y se utiliza rel="nofollow" para los enlaces.