Android Push Notification ( Parte 1 – Cliente )

Las Notificaciones push son por hoy una de los mejores features (Opino yo) que han tenido los móviles, ya que le da al developer la opción de poder interactuar de la manera que quiera con el usuario final y poder así brindarle un buen producto de calidad y una buena experiencia.

Desde enviarle una notificación de un chat o mail hasta hacer que su celular se comporte de forma que el developer quiera (Evil inside).

Hoy dia hay varias alternativas para poder implementar las notificaciones push desde proveedores terceros hasta el mismo google con GCM (Google cloud message) y el que estaremos usando para este tutoriral.

Ahora mismo un poco de la interacciones que suceden para poder llevar acabo esto.

Flow Interation

 

 Detalles de las interacciones

Paso 1 & 2:

Desde el móvil la aplicación se conecta al CGM y solicita un identificador.

Paso 3:

Desde la aplicación buscamos la manera de almacenar ese identificador retornado por GCM. Digo la manera por que el hecho es que el identificador se genero y depende de nosotros guardarlo.

Paso 4:

Desde nuestro servidor de aplicación enviamos las peticiones al GCM para que este luego procesa a enviar los push al dispositivo especifico.

 

Antes de comenzar a coder debemos primero realizar los siguientes pasos.

1.Antes de comenzar debemos crear un projecto en el Google console Developer.

Google_Developers_Console

2.Luego debemos agregarle la api de Google Cloud Message a nuestro Projecto

Google_Developers_Console_api

3.Generar una key para nuestro projecto.

Google_Developers_Console_server_keyGoogle_Developers_Console_ip_key

 

 

Una vez hecho todo Esto, Mano en el codigo.

Crear un projecto Android Simple.

Incluirle el google-play-service-lib

Agregar estos permisos a nuestra applicacion.

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

Dentro del tag de application agregar esto, sino les dara un error.

    <meta-data
            android:name="com.google.android.gms.version"
               android:value="@integer/google_play_services_version" />

Luego agregar este permiso especial, y cambiar «com.example.projecto» por el propio.

    <permission
        android:name="com.example.projecto.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

Luego debemos crear un Servicio android que extienda de IntentService, el servicio estara encargado de generar una notificacion una vez reciba un push notificacion de GCM.

public class GCMService extends IntentService{

    private NotificationManager mNotificationManager;

    private int NOTIFICATION_ID = 1234;

	public GCMService() {
		super("Listener-Service");
	}

    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();

        sendNotification("Received: " + extras.toString());

        GCMBroadCastReceiver.completeWakefulIntent(intent);
    }

    private void sendNotification(String msg) {
        mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);

        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,new Intent(this, MainActivity.class), 0);

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
        											.setSmallIcon(R.drawable.ic_launcher)
											        .setContentTitle("Developer")
											        .setStyle(new NotificationCompat.BigTextStyle()
											        .bigText(msg))
											        .setContentText(msg);

        mBuilder.setContentIntent(contentIntent);
        mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
    }
}

Agregar el servicio que acabamos de crear a nuestro manifest.xml.

<service android:name="com.example.deveoper.GCMService" />

Ahora necesitamos crear un receiver para poder recibir las notificaciones.

public class GCMBroadCastReceiver extends WakefulBroadcastReceiver{

	private String TAG = "Broadcast receiver";

	@Override
	public void onReceive(Context context, Intent intent) {
		ComponentName comp = new ComponentName(context.getPackageName(),GCMService.class.getName());

        startWakefulService(context, (intent.setComponent(comp)));

        setResultCode(Activity.RESULT_OK);

        Log.i(TAG,"Notification receive");
	}
}

Agregar el receiver que acabamos de crear en nuestro archivo manifest.xml

        <receiver
            android:name="com.example.developer.GCMBroadCastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />

                <category android:name="com.example.developer" />
            </intent-filter>
        </receiver>

Una vez esten creado nuestro servicio y nuestro receiver procedemos a trabajar sobre la actividad donde estaremos solicitando nuestro «client-id».

En este ejemplo usare el main activity pueden usar cualquier actividad. Nuestra mainActivity estaria quedando de esta forma.

public class MainActivity extends Activity {

	private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

	private GoogleCloudMessaging gcm = null;

	private String SENDER_ID = "tu-project-id";
	private String regid;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		if( checkPlayServices(this) == true ){
			getReigstrationId(this);
		}
	}

	public void getReigstrationId(final Context context){
		new AsyncTask<Void, Void, Void>(){

			private String msg;

			@Override
			protected Void doInBackground(Void... arg0) {

				if (gcm == null) {
	                gcm = GoogleCloudMessaging.getInstance(context);
	            }

	            try {
	            	Log.i("Sender",SENDER_ID);

					regid = gcm.register(SENDER_ID);

					msg = "Movil registrado, registration ID=" + regid;

				} catch (IOException e) {
					e.printStackTrace();
				}

				return null;
			}

			@Override
			protected void onPostExecute(Void result) {

				Log.i("Developer",msg);
				Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
			}
		}.execute();
	}

	public static boolean checkPlayServices(Context context) {
	    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
	    if (resultCode != ConnectionResult.SUCCESS) {
	        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
	            GooglePlayServicesUtil.getErrorDialog(resultCode, (Activity) context,PLAY_SERVICES_RESOLUTION_REQUEST).show();
	        } else {
	            Log.i("Developer", "This device is not supported.");
	        }
	        return false;
	    }
	    return true;
	}
}

Si todos los pasos le salieron bien, tendrían como resultado un Toast con su «registratio-id» el cual es el que se usa para enviar las notificaciones.

Hasta aqui la primera parte de este tutorial.

Repositorio con el ejemplo completo

Google Cloud Meesage