Notificaciones – Android

Las notificaciones son una buena forma de darle feedback al usuario de que algo sucedió y le concierne, se debe usar estas con precaución sabiduría ya que el mal uso de las mismas podría llevar a que el usuario simplemente las inhabilite para nuestra aplicación.

NotificationCompat.Builder mBuilder =
    new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.ic_launcher)
    .setContentTitle("Mi Aplicacion")
    .setContentText("Hola mundo");

NotificationManager mNotificationManager = (NotificationManager)this.getSystemService(Context.NOTIFICATION_SERVICE);

int notificacion_id = 2345;

mNotificationManager.notify(notificacion_id, notification);

Read more “Notificaciones – Android”

Estructura de proyecto & Async HTTP Model Android

Android no nos deja realizar llamadas HTTP en el main thread por lo que para poder realizar la misma tenemos que crear un nuevo hilo de ejecución y realizar la misma, el instancia AsyncTask en una actividad o fragment puede resultarnos un poco no grato para nuestro código,nuestras vistas no necesitan saber lo que es un HTTPCODE o JSON nada de eso para nuestras vistas.

Si quieres pasar directamente al ejemplo y verlo directamente aqui esta el link del project.

Para organizar un poco nuestro codigo compartire el modelo que utilizo a la hora de comunicarme / interactuar con alguna api que retorne json o el formato que exponga la misma, este modelo digamos no podría decirse que no es mio y tampoco sabría de quien es pero con el tiempo y buscando en internet un poco de cada cosa lo he adquirido.
Read more “Estructura de proyecto & Async HTTP Model Android”

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

Consumir API json con Android

Hola que tal, Buenas. En esta entrega estaré realizando un tutorial de como consumir una api json con android, estaré trabajando con los recursos nativos de android, ósea nada de librerías de terceros por el momento.

Para realizar peticiones http estaremos usando las clases HTTPGet y HTTPPost ademas de los helpers para json JSONArray y JSONObject.

Dejaremos detras la creacion del projecto y todo lo demas relacionado con el projecot android, al final del dia no es el objetivo en este tutorial.

Digamos que tenemos una api  “http://localhost.dev/country” que acepta metodos get para retornar una lista de paises y sus respectivas capitales, Algo como esto seria lo que retorna dicha api.

 


[
    {
        country: "Republica Dominicana",
        capital: "Santo Domingo"
    },
    {
        country: "Japon",
        capital: "Tokio"
    },
    {
        country: "Venezuela",
        capital: "Caracas"
    },
    {
        country: "Portugal",
        capital: "Lisboa"
    },
    {
        country: "Espana",
        capital: "Madrid"
    },
    {
        country: "Rusia",
        capital: "Moscow"
     },
     {
        country: "Colombia",
        capital: "Bogota"
     }
]

 
Una vez sabiendo la respuesta de nuestra api podemos construirle un cliente.

//
        //service api url
        String url = 'http://localhost.dev/country';

        // declarar un client http en este caso DefaultHttpClient
        HttpClient client = new DefaultHttpClient();

        //Como nuestro servicio es un metodo get usamos HTTPGet
        HttpGet request = new HttpGet(url);

        HttpResponse response;
        List entityResult;

        try {
            //Ejecutamos el request ya compuesto
            response = client.execute(request);

            StatusLine statusLine = response.getStatusLine();

            //El statusLine retorna el resultado del request a nivel de statusCode
            //AKA ( 200,404,500,401,403... )
            if (statusLine.getStatusCode() == HttpStatus.SC_OK) {

                //Si queremos el resultado del servicio (json) debemos de obtenerlo del payload del request
                //Que es obtenido como un InputStream el cual tendremos que convertir a String
                InputStream in = response.getEntity().getContent();

                
                BufferedReader buffered = new BufferedReader(new InputStreamReader(in));
                StringBuilder fullLines = new StringBuilder();

                String line;
                
                // 
                while ((line = buffered.readLine()) != null) {
                    fullLines.append(line);
                }

                String result = fullLines.toString()

                JSONArray objetos = new JSONArray(result);

                for(int i=0;i<objetos.length;i++){

                    JSONObject objeto = new JSONObject(objetos[i]);

                    /*

                        cada objecto sera compuesto por esto
                        {
                            country: "pais",
                            capital:"capital"
                        }

                    */

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

//

 
Para obtener cualquier valor de nuestro objeto json basta con solo decir, mas detalles en la pagina de documentacion de JSONObject

//
    objeto.getString
    objeto.getInt

    objecto.JSONObject

//

 
Este metodo (wrap) es el que usaremos para convertir el inputStream a un String y poder parsearlo a json.

//
	public static String inputStreamToString(InputStream in) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(in));

		StringBuilder sb = new StringBuilder();

		String line;

		while ((line = br.readLine()) != null) {
			sb.append(line);
		}

		return sb.toString();
	}

//

 
Eso seria todo si todos los metodos fueran de tipo GET pero en ocaciones tenemos metodo que reciben solo POST y parametros dentro del payload (json). El codigo seria bastante parecido, la diferencia principal es el uso de HTTPPost en vez de HTTPGet.

//
        String url = 'url_to_you_server_api.dev/postservice'

        HttpClient client = new DefaultHttpClient();

        HttpPost request = new HttpPost(url);

        JSONObject parametros = new JSONObject();

        parametros.put("usuario","usuario");
        parametros.put("clave","top_secret");

        StringEntity jsonEntity = new StringEntity( dataJson.toString() );

        HttpPost request = new HttpPost(url);

        //Agregar esto ya que algunos frameworks (nodejs frameworks) necesitan esto
        //para poder parsear los payloads automaticamente
        request.addHeader("Content-Type","application/json");

        //Se configura el payload a enviar al servicio
        request.setEntity(jsonEntity);

        //Ejecutamos el request ya compuesto
        response = client.execute(request);

        //De este punto en adelante es los mismo que una llamada GET al servicio.
        StatusLine statusLine = response.getStatusLine();
//

 
Como pueden notar realizar llamadas POST y GET con android es bastante facil y simple, Hoy dia ya hay varios frameowrks que abstraen esta funcionalidad de tener que relizar el request y parsear el json.

Android-async-http

robospice

Saludos.