Bienvenidos sean a este post, hoy hablaremos sobre como podemos utilizar al protocolo HTTP por medio de Android, para ello se pueden utilizar dos conjunto de librerias: java.net.* o org.apache.common.httpclient.*, nosotros vamos a hacer una prueba simple con nuestro navegador donde podemos buscar un dato particular y la forma de trabajo es muy similar a lo visto en el post anterior, donde por medio de GET enviaremos la informacion que necesitamos obtener, por ejemplo podemos buscar en Google las coincidencias con la palabra Lionel Messi

Si bien podemos buscarlo directamente y tendremos una URL incomprensible o podemos usar la siguiente equivalencia:

https://www.google.com/search?hl=es&q=”Lionel Messi”

Con ella obtendremos un resultado similar al de google, en este caso primero tendremos el dominio google.com luego esta search donde siempre nuestro primer caracter sera el signo de interrogacion (?) para el envio de informacion, hl es la forma de informar el lenguaje (en este caso es para español) y luego por medio del simbolo ampersand (&) agregaremos mas informacion donde le diremos que en q envie la palabra Lionel Messi y las comillas sirven para decirle que lo busque en exclusividad.

Nota: El signo de interrogacion se usa como primer simbolo para enviar informacion, si necesitamos enviar mas informacion debemos usar el ampersand para cada dato que enviemos

Para nuestro caso utilizaremos el dato de las coincidencias encontradas y en este caso el valor esta despues de la palabra “Cerca de” pero en otros buscadores puede variar (p.e a Aproximadamente), la tecnica para obtener lai informacion que necesitamos se llama Web Scraping pero para este caso utilizaremos una version simple para obtener esta informacion por medio de una aplicacion en Android, para ello crearemos una nueva app con Android Studio con las siguientes caracteristicas:

  • Application Name: HTTP
  • Domain Company: example.org
  • API SDK Minimum: 14
  • Add an Activity: Empty Activity
  • Activity Name: MainActivity
  • Layout Name: activity_main

Con nuestra aplicacion creada procedamos a modificar el layout generado por defecto con el siguiente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <EditText
        android:id="@+id/EditText01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Palabra a buscar" />

    <Button
        android:id="@+id/Button01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="Buscar"
        android:text="Buscar en google" />

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="8pt" />

</LinearLayout>

Este layout es bien simple, tendremos primero un cuadro para ingresar un texto (EditText01), luego el boton para ejecutar la accion Buscar (Button01) y por ultimo un cuadro de texto para ver nuestro resultado (TextView01), con esto realizado pasemos a modificar la clase MainActivity con el siguiente codigo:

package org.example.http;

import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

public class MainActivity extends AppCompatActivity {

    private EditText entrada;
    private TextView salida;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        entrada=(EditText) findViewById(R.id.EditText01);
        salida=(TextView) findViewById(R.id.TextView01);
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy
                .Builder().permitNetwork().build());
    }

    public void Buscar(View view){
        try{
            String palabras = entrada.getText().toString();
            String resultado = resultadoGoogle(palabras);
            salida.append(palabras + " -- " + resultado + "\n");
        }
        catch (Exception e){
            salida.append("Error al conectar!!!\n");
            Log.e("HTTP", e.getMessage(),e);
        }
    }

    String resultadoGoogle(String palabras) throws Exception{
        String pagina = "", devuelve = "";
        URL url = new URL("https://www.google.es/search?hl=en&q=\""
                + URLEncoder.encode(palabras,"UTF-8") + "\"");
        HttpURLConnection conexion = (HttpURLConnection)
                url.openConnection();
        conexion.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0;"
                + "Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                + "Chrome/74.0.3729.169 Safari/537.36");
        if (conexion.getResponseCode()==HttpURLConnection.HTTP_OK) {
            BufferedReader reader = new BufferedReader(new
                    InputStreamReader(conexion.getInputStream()));
            String linea = reader.readLine();
            while (linea!=null){
                pagina+=linea;
                linea=reader.readLine();
            }
            reader.close();
            int ini = pagina.indexOf("About");
            if (ini != -1){
                int fin = pagina.indexOf(" ", ini + 16);
                devuelve = pagina.substring(ini + 6, fin);
            } else {
                devuelve = "no encontrado";
            }
        } else {
            salida.append("Error: " + conexion.getResponseMessage() + "\n");
        }
        conexion.disconnect();
        return devuelve;
    }
}

Este codigo es simple, primero crearemos los dos objetos que se encargaran de ser nuestro enlace entre el codigo Java y los elementos del layout, donde entrada estara vinculado al elemento EditText01 y salida sera para TextView01, luego en el metodo onCreate() estableceremos los dos enlaces por medio del findViewById(), despues vendra el StrictMode el cual como dijmos anteriormente en otro post, es una herramienta que nos informa la forma que estamos conectandonos a la red y ante algun error o eventualidad nos informara de la misma.

Nuestro siguiente metodo sera Buscar(), el cual esta asignado al onClick del boton del layout, en este metodo tendremos un bloque try/catch, en el try crearemos dos variables de tipo String llamadas palabras, la cual tomara el valor que ingresamos en entrada, y resultado que contendra el valor de nuestra busqueda en google, este metodo lo veremos a continuacion y que recibe los valores ingresados en palabras y por ultimo agregaremos ese texto a la salida por medio de append().

En el siguiente metodo, resultadoGoogle(), en este metodo crearemos dos variables vacias llamadas pagina y devuelve ambas de tipo String, luego crearemos un objeto de tipo URL llamado url donde le asignaremos la siguiente direccion:

https://www.google.es/search?hl=en&q=\”” + URLEncoder.encode(palabras,”UTF-8″) + “\”

En este caso como lo explicamos anteriormente hl definira el lenguaje de respuesta para nuestra consulta y en este caso es ingles, en q informaremos las palabras a buscar pero para que se realice correctamente utilizaremos el metodo encode de URLEncoder, pasaremos el contenido de palabras y UTF-8 sera el tipo de codificacion utilizado, luego crearemos un objeto llamado conexion del tipo HttpURLconnection y por medio del objeto url usaremos a openConnection() para ejecutarlo, a conexion le enviaremos una propiedad llamada User-Agent y todo la linea para identificarlo como PC, porque el google para PC nos devuelve el dato que necesitamos extraer y el de los moviles no lo hace, despues por medio de un condicional chequearemos si la conexion devuelve la respuesta HTTP_OK, en caso de ser verdadero crearemos un objeto llamado reader del tipo BufferedReader donde por medio de new crearemos el objeto de este tipo y por medio de InputStreamReader le daremos la posibilidad de leer desde el stream creado gracias a conexion, tendremos una variable de tipo String llamada linea donde por medio de readline() leeremos las lineas del objeto reader, en un bucle while mientras linea sea distinta de null agregaremos la linea a la variable pagina, y volveremos a leer otra linea de reader y repetiremos el ciclo, una vez terminado el ciclo cerraremos a reader.
Despues crearemos variable de tipo int llamada ini donde por medio de indexOf() buscaremos en pagina la palabra About, un condicional chequeara si ini es distinto de -1, en caso de ser verdadero creara una variable llamada fin donde buscara un espacio a partir del valor de ini sumado 16, la siguiente linea asignara a devuelve una substring de pagina comprendida entre ini + 6 lugares y el valor obtenido en fin, este es el verdadero encargado de obtener el valor que deseamos recuperar, y en caso contrario de que el valor de ini haya sido -1 asignaremos a devuelve el valor de “no encontrado” y en el caso de que la conexion no se hubiera realizado correctamente en salida agregara un mensaje de error.
Despues de todo esto procede a cerrar a conexion y por ultimo entrega el valor asignado a devuelve.

Con todo esto realizado solo nos resta una ultima modificacion en el manifesto de Android, AndroidManifest.xml, donde debemos agregar la siguiente linea:

<uses-permission android:name="android.permission.INTERNET" />

Con esta linea le permitiremos a nuestro dispositivo tener acceso a internet, con estas modificaciones realizadas podemos compilarlo y probarlo como se ve en el siguiente video

En este caso hago una prueba de tres busquedas, para este caso podemos ver como con cifras elevadas cuando buscamos a Argentina o Lionel Messi obtenemos una respuesta correcta, en cambio cuando busco a Tinchicus me trae el valor pero algunos datos mas innecesarios 😱

En resumen, hemos visto como podemos interactuar con Android y HTTP, en este caso hemos visto como enviar una direccion web, como enviar un dato de identificacion de agente al servidor, tambien hemos visto como se puede extraer una informacion en particular, en este caso las coincidencias de una busqueda, si bien no es el metodo mas eficaz es un buen metodo para entender el concepto, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios