Ir al contenido principal

Desarrollo en Android T17 – REST Webservice envío de parámetros por método POST

Desarrollo en Android T1 – REST Webservice envío de parámetros por método POST

Como se mostró en tutorial anterior el uso de la arquitectura REST facilita en intercambio de información entre un servidor remoto y el dispositivo con Android, utilizando el protocolo HTTP para el envío y recepción de la información.

En este tutorial se muestra como enviar parámetros a un webservice y procesar la respuesta del mismo, específicamente se realizará la consulta de un contacto utilizando su id como parámetro de referencia.


1. Retomando la base de datos agenda, se crea el webservice encargado de recibir el id del contacto, para posteriormente realizar una búsqueda, y en caso de encontrar el contacto lo codifica utilizando Json para su posterior tratamiento en Android, el nombre del archivo será getContact.php


$db_host = "localhost";
$db_name = "agenda";
$db_user = "root";
$db_password = "";
$connection = mysql_connect($db_host, $db_user, $db_password) or die("Connection Error: " . mysql_error());
mysql_select_db($db_name) or die("Error al seleccionar la base de datos:".mysql_error());
@mysql_query("SET NAMES 'utf8'");

if(isset($_POST["id_contacto"])){

$id_contacto = $_POST["id_contacto"];
$sql_query = "SELECT * FROM contactos WHERE id_contacto=$id_contacto;";
$result = mysql_query($sql_query);
$rows = array();
while($r = mysql_fetch_assoc($result)) {
$rows[] = $r;
}
print json_encode($rows);
}else
echo "No existe el contacto";
mysql_close($connection);
?>



2. Para este ejemplo se crea un nuevo Activity y dentro del layout se agrega un EditText y un Button que permitirán a los usuarios poder escribir el número del id de contacto que desea buscar, a continuación se muestra el diseño del Layout, donde además hay 3 TextView para mostrar el Nombre, Teléfono y Email del contacto buscado.

xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.sax.agendarest.SearchActivity">
    <TextView
        android:id="@+id/tv_search_title"
        android:textSize="20dp"
        android:textAlignment="center"
        android:textColor="@color/colorPrimary"
        android:text="@string/title_activity_contact_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_id_contact"
        android:text="Id Contact"
        android:textColor="@color/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/et_id_contact"
        android:inputType="number"
        android:textColor="@color/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/btn_search"
        android:text="@string/search"
        android:textColor="@color/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_nombre"
        android:textSize="18dp"
        android:textColor="@color/colorValues"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_email"
        android:textSize="18dp"
        android:textColor="@color/colorValues"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_telefono"
        android:textSize="18dp"
        android:textColor="@color/colorValues"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>


En la siguiente imagen se muestra como se vera la interfaz del Activity.




3. A continuación se agregan las siguientes librerías, que permitirán mostrar vincular los TextEdit, el EditText y el Button que se diseño en el layout.

import android.io.* son las librerías que permiten el manejo de las cadenas de texto que se envían entre el servidor de base de datos y la App Móvil.

import android.net.* son las librerías que permiten el uso del protocolo HTTP, para el envió y recepción de los datos.

import org.json.* estas librerías permiten la codificación y de-codificación de las cadenas de texto en formato Json, es decir permite identificar los objetos y los valores asignados a cada uno.

import android.app.AlertDialog;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import java.net.HttpURLConnection;
import java.net.URL;


4. Dentro de la clase se declaran las siguientes variables globales, que permitirán vincular la vista con el código que controlará su comportamiento.

Como se ve en el siguiente código se declara la variable getContactURL que es donde se almacena la URL del webservice que se creo en el punto 1.

Nota: para que esto funcione se debe utilizar la IP del servidor, y tener en cuenta que si se trabaja de forma local, tanto el servidor como el dispositivo móvil deben estar en la misma red.

private String getContactURL = "http://192.168.0.28/agendaweb/webservices/getContact.php";
private Button btn_search;
private EditText et_id_contacto;
private TextView tv_nombre;
private TextView tv_email;
private TextView tv_telefono;

5. Dentro del método onCreate del Activity se inician las variables declaradas con los componentes de la vista, además se establece el evento OnClick del botón con un método que se creara en el siguiente punto.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search);
    et_id_contacto = (EditText)findViewById(R.id.et_id_contact);
    tv_nombre = (TextView)findViewById(R.id.tv_nombre);
    tv_telefono = (TextView)findViewById(R.id.tv_telefono);
    tv_email = (TextView)findViewById(R.id.tv_email);

    btn_search = (Button)findViewById(R.id.btn_search);
    btn_search.setOnClickListener(onClickListener);
}


6. En el método OnClickListener se detecta el elemento que genero el evento y si este fue el botón invoca el método btn_search_onClick();

El uso de estos métodos permiten separar el funcionamiento de los eventos, de forma que el código sea más fácil de entender.

private View.OnClickListener onClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(v ==  btn_search)
            btn_search_onClick();
    }
};


7. En este método se obtiene el id_contacto que haya escrito el usuario en la vista, y posteriormente utilizando un Uri.Builder se agregan tantos parámetros como se necesiten, para esto se utiliza la siguiente línea de código

builder.appendQueryParameter("id_contacto", id_contacto);

Esta se puede repetir tantas veces como se necesita, indicando el nombre del parámetro y el valor que se va a enviar.

Con la linea siguiente se convierten los parámetros a un query que sera interpretado por el webservice.

builder.build().getEncodedQuery();

y finalmente se invoca al método  performPostCall(URL,parámetros), que es el encargado en establecer la conexión con el servidor remoto y recibir la respuesta de este.

private void btn_search_onClick(){
    String id_contacto= et_id_contacto.getText().toString();

    Uri.Builder builder = new Uri.Builder();
    builder.appendQueryParameter("id_contacto", id_contacto);
    String queryParams = builder.build().getEncodedQuery();

    performPostCall(getContactURL, queryParams);
}

8. El método performPostCall recibe como parámetro la URL a la que se va a conectar, y los parámetros que le va a enviar.

La variable HttpURLConnection conn es la que permitirá configurar la conexión con el servidor, indicando el tiempo que debe esperar si el servidor no responda, indica el método que usara para enviar la información, en este caso POST, y por último habilita la entrada y salida de datos (input, output).

El método writer.write(query); es el que envía todos los parámetros que se almacenaron anteriormente.

Una vez enviada la información el servidor revuelve un código indicando el estado de la petición, por ejemplo si la respuesta fuera un 404 significaría que el webservice no esta disponible, si la respuesta es un Ok esta se valida con un if como se muestra en la siguiente línea y posteriormente esta se almacena en  bufferedReader para formatearla posteriormente con json.

 if(responseCode == HttpURLConnection.HTTP_OK) 

private void performPostCall(String requestURL, String query){
    URL url;
    String webServiceResult="";
    try{
        url = new URL(requestURL);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);
        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os,"UTF-8"));
        writer.write(query);
        writer.flush();
        writer.close();
        os.close();
        int responseCode = conn.getResponseCode();
        if(responseCode == HttpURLConnection.HTTP_OK){
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = "";
            while ((line = bufferedReader.readLine()) != null){
                webServiceResult += line;
            }
            bufferedReader.close();
        }else {
            webServiceResult="";
        }
    }catch (Exception e){
        e.printStackTrace();
        Log.e("SearchActivity",e.getMessage());
    }
    if(webServiceResult!=null)
        parseInformation(webServiceResult);
    else
        Message("Search","Contact not found");
}

9. Al utilizar la variable jsonArray y almacenar la cadena de texto recibida por el servidor, esta se convierte automáticamente en un array que almacena cada uno de los registros que regreso la consulta del webservice. En este caso solo debe contener un registro o ninguno en caso de que el id_contacto buscado no coincida con alguno de los almacenados en la base de datos.

En el tutorial anterior los datos se almacenaban en un adapter y eran mostrados en un ListViewaquí los datos se almacena temporalmente en variables de tipo String, y posteriormente se muestran en los TextView de la vista usando las siguientes lineas de código.

nombre = jsonObject.getString("nombre");
tv_nombre.setText(nombre);

private void parseInformation(String jsonResult){
    JSONArray jsonArray = null;
    String id_contacto;
    String nombre;
    String telefono;
    String email;
    try{
        jsonArray = new JSONArray(jsonResult);
    }catch (JSONException e){
        e.printStackTrace();
    }
    for(int i=0;i<jsonArray.length();i++){
        try{
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            id_contacto = jsonObject.getString("id_contacto");
            nombre = jsonObject.getString("nombre");
            telefono = jsonObject.getString("telefono");
            email = jsonObject.getString("email");
            tv_nombre.setText(nombre);
            tv_telefono.setText(telefono);
            tv_email.setText(email);
        }catch (JSONException e){
            e.printStackTrace();
        }
    }
}


10. Se crear un método Message que recibe un titulo y un mensaje para posteriormente mostrarlo al usuario utilizando un AlertDialog.

private void Message(String title, String message){
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
    alertDialog.setTitle(title);
    alertDialog.setMessage(message);
    alertDialog.show();
}

11. Antes de compilar e instalar la app en el dispositivo móvil hay que verificar que en el archivo Manifest.xml se encuentren activados los permisos para acceder a Internet, utilizando la siguiente línea.

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


El resultado al ejecutar la App y realizar una consulta es el siguiente:


Comentarios

Entradas más populares de este blog

Creación de Librerías en Java

Creación de Librerías en Java   Las librerías son un conjunto de clases con funciones especificas que ayudan a desarrollar aplicaciones más complejas de una forma sencilla, por ejemplo si se requiere realizar cálculos matemáticos y emplear el funciones como el Seno o Coseno, simplemente se importa la librería Math y se utilizan estos métodos, en lugar de desarrollarlos. Java cuenta con una extensa lista de librerías disponibles dentro del JDK o desarrolladas por terceros, pero también existe la posibilidad de desarrollar librerías propias para reutilizar de forma más eficiente el código, por ejemplo si se trabaja de forma cotidiana con conexión a base de datos, se pueden desarrollar métodos genéricos que realicen la conexión, que validen las consultas, etc. de forma que su uso reduzca el tiempo de desarrollo e incremente la productividad. Para este tutorial se van a crear dos proyectos en NetBeans, uno sera la librería y el otro proyecto hará uso de esta.

Elegir la clase a ejecutar en NetBeans, MVC

Elegir la clase a ejecutar en NetBeans Para que java pueda ejecutar una aplicación esta debe tener un método conocido como punto de entrada, este método tiene la sintaxis: void static void main(String [] sax){ //código } En ocasiones en una aplicación tiene varios puntos de entrada, que pueden servir para probar diferentes partes de la aplicación sin tener que recorrer o pasar por varias clases, para esto se puede seleccionar directamente en las propiedades del proyecto que clase será la principal.

Librerías JOptionPane para generar ventanas de entrada y salida de datos

Para poder introducir datos leídos desde el teclado existen varias formas, una de ellas hace uso de la librería javax.swing.JOptionPane que entre otras opciones permite mostrar ventanas para introducir datos, y ventanas para mostrar valores. Con el uso de esta librería se crean pequeñas interfaces definidas por el sistema, pero ya se hace uso de las librerías graficas swing, que se verán más adelante.