Google Cloud Messaging. Parte IV: Aplicación cliente

The Google Cloud Messaging (GCM) guide can be found here and is available in English, therefore I am writing these related posts in Spanish.

Esta es la parte IV de un conjunto de entradas sobre Google Cloud Messaging (GCM).


En la publicación anterior comenzamos a ver la aplicación Android cliente: la instalación de la librería GCM y la configuración del fichero AndroidManifest.xml. En esta parte vamos a terminar de mostrar la aplicación cliente viendo la parte de programación.
Necesitamos implementar básicamente tres acciones:

  • Registro del servicio GCM
  • Borrado del registro del servicio
  • Recepción de los mensajes

Registro y borrado del servicio

Lo más normal es que queramos que nuestra aplicación se registre al comienzo de su ejecución, sin que sea necesaria interacción por parte del usuario. Por este motivo, el código necesario para el registro de la aplicación a GCM lo insertaremos en el método onCreate de nuestra Activity principal. Según los requerimientos de cada aplicación, puede realizarse el registro de forma diferente.

import com.google.android.gcm.GCMRegistrar;
...

try{

   GCMRegistrar.checkDevice(this);
   GCMRegistrar.checkManifest(this);

   final String regId = GCMRegistrar.getRegistrationId(this);

   if (regId.equals("")) {
      GCMRegistrar.register(this, SENDER_ID);
   } else {
      Log.v(TAG, "Ya estoy registrado");
   }

} catch (UnsupportedOperationException e) {
   Log.e(TAG, "El dispositivo no soporta GCM.", e);
} catch (IllegalStateException e) {
   Log.e(TAG, "El manifest no está bien configurado.", e);
}

En la línea 6 comprobamos si el dispositivo soporta GCM, de lo contrario saltará una excepción que debemos capturar.
En la línea 7 se comprueba si el archivo AndroidManifest.xml está bien configurado, por lo que una vez sepamos que está correcto, podemos quitar esta llamada. Igualmente debemos tratar la posible excepción que nos saltará si la configuración está mal.
En la línea 9 buscamos el Registration ID. En el caso de que no exista, es porque aún no nos hemos registrado.
El registro se realiza en la línea 12 donde pasamos como parámetro nuestro Sender ID.

Si recordamos el proceso del servicio de GCM, en el registro debíamos indicar el Sender ID y el Application ID. El Sender ID está contenido en la constante SENDER_ID y el Application ID es tomado automáticamente por la librería de GCM. El Sender ID se obtiene desde la consola de Google APIs tal y como expliqué en la parte II.


Para borrar el registro, llamamos al método unregister.

GCMRegistrar.unregister(this);

Podemos crear una vista de configuración donde el usuario pueda desactivar las notificaciones.

Servicio receptor

Finalmente tenemos que implementar la lógica de nuestro cliente cuando le lleguen los eventos. Con el uso de la librería GCM para Android tan sólo tenemos que crear el servicio que declaramos en el manifest llamado GCMIntentService. Esta clase tiene que extender la clase base que nos proporciona la librería GCM, GCMBaseIntentService. Al extenderla podemos añadir automáticamente los métodos a implementar.

import com.google.android.gcm.GCMBaseIntentService;

public class GCMIntentService extends GCMBaseIntentService {

   @Override
   protected void onError(Context context, String errorId){
      // Error en el registro: tratamiento del error
   }

   @Override
   protected void onMessage(Context context, Intent intent){
      // Notificación recibida: informo al usuario u otra acción	
   }

   @Override
   protected void onRegistered(Context context, String regId){
      // Registro correcto: envío el regId a mi servidor	
   }

   @Override
   protected void onUnregistered(Context context, String regId){
      // Borrado correcto: informo a mi servidor
   }
}

Es tan sencillo como añadir la lógica de nuestra aplicación a estos cuatro métodos:

  • onError.
    Este método es llamado cuando intentamos registrarnos o borrarnos del servicio de GCM pero se recibe un error.
  • onMessage.
    Este método es llamado cuando los servidores de GCM envíen un mensaje al dispositivo (previo envío del mensaje de nuestro servidor a los servidores de GCM). Si el mensaje contiene datos, éstos están contenidos como extras en el intent:

    String mensaje = intent.getStringExtra("mensaje");
    
  • onRegistered.
    Este método es llamado cuando tras una solicitud de registro, se recibe el Registration ID asignado por GCM. Recordamos que este identificador debe ser enviado y almacenado en nuestro servidor.
  • onUnregistered.
    Este método es llamado cuando el dispositivo se da de baja del servicio de GCM. Debe informarse a nuestro servidor para que también lo elimine.

Los errores que pueden recibirse en el método onError se encuentran como constantes en la clase GCMConstants de la librería GCM:

  • ERROR_ACCOUNT_MISSING.
    No hay cuenta de Google asociada en el dispositivo. Nuestra aplicación debería pedir al usuario que añada una cuenta desde el gestor de cuentas en los ajustes del dispositivo.
  • ERROR_AUTHENTICATION_FAILED.
    La contraseña de la cuenta de Google es incorrecta. Nuestra aplicación debería pedir al usuario que introdujese su contraseña desde el gestor de cuentas.
  • ERROR_INVALID_PARAMETERS.
    La petición enviada por el dispositivo no contiene los parámetros que eran esperados. El dispositivo no soporta GCM.
  • ERROR_INVALID_SENDER.
    No se reconoce el Sender ID. En este caso debemos revisar bien el Sender ID que estamos usando en nuestra aplicación, y comprobar que coincide con el que obtuvimos en la consola de Google APIs.
  • ERROR_PHONE_REGISTRATION_ERROR.
    Registro incorrecto del dispositivo. El dispositivo no soporta GCM.
  • ERROR_SERVICE_NOT_AVAILABLE.
    El dispositivo no pudo leer la respuesta, o el servidor GCM devolvió un código 500/503. No es un error de nuestra aplicación, por lo que deberemos reintentarlo más tarde.
Share Button

13 Comments

  1. tengo una duda cuando instalo y desinstalo la app recibo la notificacion duplicada no se como desactivar o elimnar los token con los que estan dado de algo he investigado pero nada no se si puedas ayudarme gracias. y si es asi aver si podrias darme un ejemplo

  2. La teoría está muy bien explicada y ordenada a detalle, fue la primera página que seguí antes de darme cuenta de que estaba desactualizada, sólo una pregunta ya que aún no la actualizas.

    – Para la parte III: que permiso o servicio debo escribir para que la aplicación se mantenga viva, esperando los mensajes devuletos desde GSM, como el messenger de algunas redes sociales que se mantinen vivas, y te llegan notifcación, incluso si salí de ellas. Me dí cuenta de que a veces no llegan las notificaciones; revise código en el servidor, código en android y no encontraba el problema y revisando en “Config” => “Administrar aplicaciones” en información de la aplicación, la aplicación estaba cerrada, creo que sólo le llegan las notificaiones cuando está en ejecución.

    1. Una de las características de GCM es que no necesitas tener tu app abierta para recibir las notificaciones. Por tanto, en este sentido no puedes controlar cuándo el sistema recibe una notificación. Tampoco debes intentar que tu app esté siempre ejecutándose. Android decide qué apps matar y cuáles no, según las necesidades del sistema. Sería mala práctica intentar que tu app esté siempre en ejecución.

  3. Hola, Belén.

    Agradecerte la ayuda que me has brindado con este completo tutorial.

    Tengo una duda, ¿dónde, en qué archivo, he de colocar el código que expones en esta cuarta parte del tutorial?

    Gracias de antemano.

    Saludos.

    1. Muchas gracias, aunque ha quedado desactualizado. El código de la cuarta parte viene descrito en el texto dónde puede colocarse: “el código necesario para el registro de la aplicación a GCM lo insertaremos en el método onCreate de nuestra Activity principal.”

  4. Buen día una pregunta no entendi muy bien de donde salio la clase GCMRegistrar espero me puedas explicar o es una clase que hiciste tu pero si es asi que se hace dentro de esa clase saludos

      1. Buenas, lo primero agradecerte el trabajo del blog, está muy bien explicado todo y facilita mucho las cosas

        Por otro lado me me preguntaba si podrías en un futuro dedicar algo de tiempo a modificar (o crear un nuevo manual) de cómo registrar el servicio GCM con la nueva API, ya que por un lado no tiene los mismos métodos que la API obsoleta, y por otro lado es algo más confusa.

        De nuevo agradecerte el manual y todo tu trabajo.

        Un saludo

    1. se capturan dentro del método onError(Context context, String errorId) de la siguiente forma:

      if (errorId.equals(GCMConstants.ERROR_ACCOUNT_MISSING) {

      } else if (errorId.equals(GCMConstants.ERROR_SERVICE_NOT_AVAILABLE)) {

Deja un comentario

Tu dirección de correo electrónico no será publicada.

Time limit is exhausted. Please reload the CAPTCHA.