Android GCM Sender

Esta entrada es una traducción al español de la que publiqué en mi blog, que está en inglés.

Motivación

Imagina que estás desarrollando una aplicación Android que necesita recibir notificaciones push. La aplicación encargada de enviar esos mensajes a GCM está siendo desarrollado por otro equipo, y no sólo no está terminada todavía, sino que además el equipo está en otro departamento de la empresa. No, de hecho está en otra empresa :-) . Quieres estar seguro de que tu aplicación cumple las especificaciones (es decir, reacciona de cierta manera cuando recibe cierta notificación), pero no quieres depender de ese otro equipo (y por supuesto, tampoco quieres desarrollar una aplicación que envíe notificaciones 😀 ):

Solución

Esa necesidad de una aplicación de envío de mensajes configurables a GCM es el segundo artefacto que Adrian Santalla y yo desarrollamos en los dos primeros hacker fridays de OSOCO, al que hemos llamado Android GCM Sender (siendo el primero el plugin de Android GCM para Grails).

Suscribe tus dispositivos usando la URL proporcionada y añade tu identificador de proyecto

Empezó siendo la aplicación de prueba para dicho plugin, pero nos dimos cuenta que sería fácil evolucionarla hasta el punto de ser útil para cualquiera: sólo necesitábamos parametrizar el identificador de proyecto (que puedes obtener creando un proyecto tipo Google API) y crear una acción que permitiese la suscripción de dispositivos Android. Puedes usar Android GCM Sender en la siguiente URL: http://grails-android-gcm-sender.herokuapp.com/.

Uso

El primer paso sería suscribir tus identificadores de dispositivo Android usando la URL http://grails-android-gcm-sender.herokuapp.com/device/subscribe?deviceToken=yourDeviceToken&projectId=yourProjectId. No olvides sustituir substitute yourDeviceToken y yourProjectId con tu identificador de proyecto e identificador de dispositivo Android, y recuerda que esta URL está pensaba para ser invocada con algún tipo de HTTPBuilder dentro de una aplicación Android – opr eso no produce ninguna salida :-). Pero si quieres usarla directamente en tu navegador, también funcionará 😀 .

Compón tu mensaje, envíalo a los dispositivos seleccionados y observa el resultado del envío

Después de eso, escribe tu identificador de proyecto en la página de inicio de Android GCM Sender y dale al botón de actulizar. Verás un formulario que te permite enviar mensajes (simples o compuestos) a uno o varios dispositivos Android. Ten en cuenta que siempre tendrás disponibles dos dispositivos falsos para el caso en que quieras hacer algún tipo de prueba con ellos. Después de rellenar el formulario. puedes darle al botón Send y verás el resultado del envío. Y si tus identificadores de dispositivo y proyecto son válidos, deberías recibir una notificación push con el mensaje que compusiste en la vista anterior 😀 .

Ten en cuenta que para mantener los datos en un volumen pequeño, tus identificadores de dispositivo y proyecto sólo se guardan durante 24 horas – piensa que en realidad es una feature y no un bug 😀 ya que así no te tienes que preocupar de des-suscribir tus dispositivos o similar. De hecho, la base de datos está en memoria, por lo que nosotros no tenemos acceso a ella.

Código fuente

Android GCM sender corre en Heroku, pero su código fuente está disponible en la cuenta Github de OSOCO, por lo que puedes alojarlo tú mismo si quieres. La aplicación ha sido desarrollada usando Grails, y a la UI se le ha añadido un poco de picante con Ajaxify.

Grails Android GCM Plugin

Nota: esta entrada también está publicada en mi blog en inglés. If you are an english reader, you might want to read that version.

Como resultado de los dos primeros hacker fridays de OSOCO, Adrian Santalla y yo publicamos el plugin de Grails para Android GCM (entre otras cosas 😀 ), cuyo código fuente está disponible en Github.

Este pequeño plugin proporciona a tu aplicación Grails acceso a Android GCM (el servicio que Googe usa para las notificaciones push de Android) a través de un servicio que es injectado en los artefactos de tu aplicación.

El plugin está publicado en el repositorio oficial de plugins de Grails, así que instalarlo es tan fácil como invocar la orden install-plugin, tras lo cual cualquier servicio, controlador, etc, de tu aplicación podrá usar el servcio androidGCMService. El siguiente ejemplo ilustra el caso de uso más básico:

$ grails create-app AwesomeApp 
$ cd AwesomeApp
$ grails install-plugin android-gcm
$ grails create-controller Cool
$ cat > grails-app/controllers/awesomeapp/CoolController.groovy << EOF
package awesomeapp

class CoolController {

    def androidGcmService

    def index() {  
        render androidGcmService.sendMessage(
            [ 
                aMessageKey : 'The message value for the key aMessageKey', 
                anotherMessageKey : 'The message value for the key anotherMessageKey' 
            ],
            ['anAndroidDeviceToken', 'anotherAndroidDeviceToken'],
            'youShallCollapseThisMessage', 'yourGCMAPIKeyProvidedByGoogle'      
        )          
    }
}
EOF
$ grails run-app
$ $ wget -O - http://localhost:8080/AwesomeApp/cool/index 2> /dev/null
MulticastResult(multicast_id=8596196938900195177,total=2,success=0,failure=2,canonical_ids=0,results: [[ errorCode=InvalidRegistration ], [ errorCode=InvalidRegistration ]])

Como se ve, el controlador intenta enviar un mensaje (el cual, por su parte, está compuesto por dos mensajes, cada uno con su clave y valor) a dos dispositivos Android, marcando el mensaje como de tipo collapse, y pasando la clave de acceso al API de GCM porporcionada por Google. Cuando el resultado es renderizado, se muestra un objeto de clase MulticastResult (dado que hemos intentado enviar el mensaje a múltiples dispositivos) con el resultado del envío del mensaje (que en este caso es un error de tipo InvalidRegistration para ambos dispositivos, ya que estamos inventándonos su identificador de registro 😀 ). Ten en cuenta que si quieres probar este ejemplo tendrás que sustituir yourGCMAPIKeyProvidedByGoogle con un identificador de API válido, si no lo haces el API de Android al que el plugin invoca fallará con una bonita excepción de tipo null pointer :-( .

Puedes ver una lista completa de los métodos proporcionados por el servido y de las opciones de configuración disponibles en el README del proyecto en Github.