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 ListView, aquí 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);
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