domingo, 13 de octubre de 2013

Tutorial simple de GCM a través de PHP ( Google Cloud Messaging ) nueva interface

Buenos días!
Hoy traigo un super tutoríal muy útil. se trata del servicio gratuito de Google Cloud Messaging (GCM) en castellano sería algo así como mensajería instantánea en la nube.

¿Qué es?
Si alguna vez habeis intentado hacer alguna aplicación que necesite recibir información (tipo chat) cada determinado tiempo os habréis topado con el problema de tener que definir X segundos para que se conecte al servidor y compruebe si hay algún mensaje pendiente de recibir. Esto supone muchos problemas el primero todo el trafico que se genera tontamente y el segundo y aún más importante es que se come la batería del teléfono en pocas horas.


Google trae la solución! se trata de una Api que automatiza el proceso de recibida de información si necesidad de indicar cada cuanto tiempo tiene que revisar el servidor para comprobar si hay información nueva. Es algo costoso hacerla funcionar pero una vez la tenéis funcionando veréis lo bien que funciona.

Normalmente GCM se utiliza para notificaciones de aplicaciones. Y eso vamos hacer en este tutorial sin embargo más adelante publicaré unos Post en los cuales intentaremos jugar y sacarle más partido a este sistema de mensajería instantánea.

Empecemos, lo primero de todo es registrarse en los servicios Cloud de Google para ello entrar aquí:

- https://cloud.google.com

Una vez entremos, nos registremos con nuestra cuenta de google y nos logueemos (posiblemente nos haga verificar nuestro numero de mobil, e-mail, etc...)
Al entrar le damos a crear nuevo proyecto, de nombre yo voy a poner tutorial_html5 la Id voy a dejar la que ponga.

Ahora en el menú de la izquierda entramos a Apis y Autentificación -> Apis, y buscamos la opción de Google cloud Messaging for android y lo activamos.
Una vez activado nos vamos a la opción del Menú Aplicaciones registraras y rellenamos el pequeño formulario.

Abrimos el Eclipse creamos nuevo proyecto Android, una vez creado el proyecto vamos a añadir la aplicación de Google Cloud Messaging a nuestro proyecto para ello entramos en SDK android la buscamos marcamos y damos a instalar. en mi caso ya está instalado:

Una vez instalado vamos a nuestra carpeta del SDK del disco local y localizamos el siguiente archivo .jar


Al tener localizado el archivo gcm.jar lo copiamos y pegamos dentro de la carpeta libs de nuestro proyecto, una vez dentro lo añadimos al proyecto de la siguiente manera:


Una vez añadido el el gcm al proyecto ya lo tenemos preparado ahora vamos a crear nuestro simple proyecto ya podemos empezar la pequeña aplicación.

Creamos el Cliente Android
En nuestro caso se llama MainActivity.java este es el código totalmente comentado:
package com.tywors.tutorialhtml5;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
//Importamos la libreria de google
import com.google.android.gcm.GCMRegistrar;

public class MainActivity extends Activity {
 //Creamos un TAG para la app
 String TAG = "Tutorialeshtml5.com";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //Comprovamos que todo funcione
        GCMRegistrar.checkDevice(this);
        GCMRegistrar.checkManifest(this);
        // Register Device Button
        Button regbtn = (Button) findViewById(R.id.register);
 
        regbtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG, "Registering device");
                // Registramos el mobil en GCM utilizando el GCMIntentService
                //Marcará error porque ún no lo hemos creado
                GCMRegistrar.register(MainActivity.this,
                        GCMIntentService.SENDER_ID);
            }
        });
    }

}
Si os avéis fijado os dará un error al no encontrar el boton registrar en el layout, solo tenemos que ir al layout y crear un botón que se tenga de Id register.

Ahora crearemos el GCMIntentService.java que es el encargado de comunicarse con el Cloud y recibir los mensajes. Aquí el código totalmente comentado:
import android.content.Context;
import android.content.Intent;
import android.util.Log;
 
import com.google.android.gcm.GCMBaseIntentService;
 
public class GCMIntentService extends GCMBaseIntentService {
 
    private static final String TAG = "tutorialeshtml5.com";
 
    // Aquí ponemos nuestro código de PROYECTO ID que nos dió android
    public static final String SENDER_ID = "--ID--";
 
    public GCMIntentService() {
        super(SENDER_ID);
    }
    @Override
    protected void onRegistered(Context context, String registrationId) {
        Log.i(TAG, "onRegistered: registrationId=" + registrationId);
    }
    @Override
    protected void onUnregistered(Context context, String registrationId) {
        Log.i(TAG, "onUnregistered: registrationId=" + registrationId);
    }
    @Override
    protected void onMessage(Context context, Intent data) {
        String message;
        ///////////////////////////////////////
        //Aquí recibimos el mensaje que nos llega del servidor
        ///////////////////////////////////////
        message = data.getStringExtra("message");
       //Lo mostramos en el CatLog:
        Log.d("******", message);
    }
 
    @Override
    protected void onError(Context arg0, String errorId) {
        Log.e(TAG, "onError: errorId=" + errorId);
    }
}
Es importante poner nuestro ID en el código donde dice SENDER_ID
Para saber que código ID tenemos lo vemos en la web de google justo despues de crear la aplicación:


Ahora hay que introducir las clases y los permisos en el Manifest.xml de nuestro proyecto:
 <uses-permission android:name="android.permission.INTERNET" /> 
 <permission android:name="com.tywors.tutorialhtml5.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="com.tywors.tutorialhtml5.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
También hay que añadir la clase que hemos creado en el Manifest.xml
<activity android:name="com.tywors.tutorialhtml5.GCMIntentService"
            android:label="@string/app_name" ></activity>
Tambien hay que añadir lo siguiente antes del < / aplication >
 <service android:name=".GCMIntentService" />
        <receiver android:name="com.google.android.gcm.GCMBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE">
                <action android:name="com.google.android.c2dm.intent.REGISTRATION">
 
                <category android:name="com.androidbegin.gcmtutorial">
            </category></action></action></intent-filter>
        </receiver></service>
Una vez todo listo ejecutamos la aplicación en el movil damos al botón que hemos creado antes en el layout y miramos el Logcat y aparecerá un RegisterId lo capiamos todo apartir del RegisterID eso será el código único para enviar mensages o información al terminal desde una web que mostraré a continuación. Este será el Id del LogCat:
Ya tenemos nuestro ID. Para comprobar que todo funciona bien Vamos al siguiente LINK:


En ese link nos pedirás el Google API Key : lo miramos en el Cloud:
Despues pedirá Device Registration ID : lo miramos en el Cloud dentro de la aplicación creada:

Después nos pedirá la ID propio del terminalm el que teniamos en el LogCat:

Y finalmente en Mensage escribimos el mensajes que queramos que llegue, en mi caso: Funciona! y vemos através del LogCat que llega al terminal correctamente! :D

Todo esto a sido creado por mí sacado de http://www.androidbegin.com/tutorial/android-google-cloud-messaging-gcm-tutorial/ Está en ingles y la versión antigua de Google yo lo he adaptado.

Espero que os funcione perfecto ya que este tutorial tiene bastante complejidad. Os dejo el Projecto para descargar, simplemente tendréis que modificar el ID en el archivo GCMIntentService.class

Para descargar el Proyecto:

Muchas gracias a todo, Espero comentarios!


9 comentarios:

  1. Muy buen tutorial amigo. Gracias!. pero cómo se puede implementar un servidor propio y que sea capaz de recibir datos de un dispositivo android y enviarlos a otro dispositivo. Sería fabuloso un tutorial que indique como realizarlo. Un saludo, De antemano gracias. :)

    ResponderEliminar
    Respuestas
    1. No aré un tutorial ya que sería muy extenso y personalizado. Pero deberías seguir estos pasos:

      -Almacenar el Id de GCM del terminal en una base de datos.
      -Recoger ese ID de la base de datos desde otro terminal relacionandolo ya sea con numero de teléfono, nick, etc. Enviar el Id de destino junto a un mensaje al Php y lo recibirá el otro dispositivo.

      Pensando y dandole vueltas resolverás tu problema. Un +1 nos ayuda a todos! :D

      Eliminar
  2. buen tutorial, se podran enviar imagenes? obvio que con este codigo no pero me refiero a poder enviar un jpeg por el gcm?
    salu2

    ResponderEliminar
    Respuestas
    1. Estoy trabajando en ese tema y seguramente saque un tutorial de 'jugando con GCM' aunque imagenes no se podrán pasar por el tamaño creo que solo acepta 40kb no estoy seguro. Pero siempre abrá alguna técnica que se pueda utilizar. seguiré mirando.

      Muchas gracias recuerda que un +1 nos ayuda a todos :D

      Eliminar
  3. Que tal, a la hora de ejecutar el proyecto me sale este error: java.lang.NoClassDefFoundError: com.google.android.gcm.GCMRegistrar ya instale todo del SDK y nada reinicie la computadora y nada, alguna solucion? saludos...

    ResponderEliminar
  4. Ese método gcmregistrar se encuentra obsoleto y se utiliza Google play Services para la conexion no el gcm, el gcm.bar es la versión anterior

    ResponderEliminar
  5. Hola a todos!! al ejecutar la aplicacion desde el servidor siempre me devuelve "error 401 unauthorized". He leido que tiene que ser por el API Key, pero tengo puesta la correcta. Que puede pasar?

    ResponderEliminar
    Respuestas
    1. Hola Javier se me ha presentado el mismo problema que expones en tu pregunta, me gustaría saber si encontraste alguna solución y si si te es posible compartirla ya que igual he revisado API KEY y registrado el dispositivo en el proyecto correcto pero me sigue saliendo el error. De antemano muchas gracias.

      Eliminar
    2. Parece que han cambiado la Api después de la integración de Google Play Services.

      Eliminar