En este post veremos como enviar solicitudes GET y POST a un API RestFul desde un dispositivo con android.
Nuestra aplicación consistirá en un pequeño formulario para escribir un nombre y una edad y enviar estos al servidor quien dará una respuesta (Result:200). Si bien GET se utiliza más que todos para realizar consultas y POST para insertar datos por la cantidad de información que maneja cada uno, GET también puede ser utilizada para enviar pequeña cantidad de datos.
Necesitamos
Si se usara el Emulador android necesitamos:
Si se usara un dispositivo físico necesitamos
Nivel: Intermedio
Tiempo: 20 minutos
Proyecto en Eclipse
1. ApiRest
Construir un Api REST no esta entre los objetivos de este tutorial, por lo que reduciremos nuestro api de prueba a un archivo PHP que recibirá peticiones GET/ POST y retornara un resultado en formato JSON, el nombre del archivo es «apirest.php» y el código es el siguiente
<?php if( $_GET ) { $data = json_encode($_GET); $datares = array( 'Result'=>"200" ); print ( json_encode( $datares ) ); saveLog($data,"GET"); } else { $data = file_get_contents("php://input"); $datares = array( 'Result'=>"200", 'data'=>$data ); print ( json_encode( $datares ) ); saveLog($data,"POST"); } function saveLog($data,$peticion) { $linea = "-------------------------------------------------------------------------------"; $buffer = $peticion . " :: " .$data . "\r\n" . $linea; $file = 'log.txt'; if (file_exists($file)) { $buffer = file_get_contents($file) . "\r\n" . $buffer; } $success = file_put_contents($file, $buffer); } ?>
Crea este archivo en tu servidor local o sube a tu hosting, la dirección para acceder a este archivo es de la forma: «http://localhost/api/apirest.php» y lo que hace es procesar peticiones GET o POST darles un formato JSON, guardar en un archivo log.txt y retornar un resultado también en formato JSON de la forma:
{"Result":"200","data":""}
donde Result:200 quiere decir que el proceso se realizo correctamente.
2. Proyecto Android
Crea un nuevo proyecto android en Eclipse que se llamará RestFulGP, a continuación dale la siguiente estructura:
Nuestro proyecto contará con:
3. Permisos
Necesitamos añadir un permiso de Internet al archivo AndroidManifest.xml, ábrelo y añade:
<uses-permission android:name="android.permission.INTERNET" />
4. Interfaz de usuario
Abre el activity_main.xml y pega el siguiente código:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" 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=".MainActivity" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/str_name" /> <EditText android:id="@+id/txtName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:ems="10" android:inputType="textPersonName" > <requestFocus /> </EditText> <TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="@string/str_edad" /> <EditText android:id="@+id/txtAge" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:ems="10" android:inputType="number" /> <Button android:id="@+id/btnGet" android:layout_marginTop="20dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/str_btnGet" /> <Button android:id="@+id/btnPost" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="@string/str_btnPost" /> <TextView android:id="@+id/txtResponse" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:text="@string/str_status" android:textAppearance="?android:attr/textAppearanceLarge" /> </LinearLayout>
Abre el archivo strings.xml y añade:
<string name="str_name">Nombre completo</string> <string name="str_edad">Edad</string> <string name="str_btnGet">Enviar por GET</string> <string name="str_btnPost">Enviar por Post</string> <string name="str_status">Status:</string>
Guarda todo y en el diseñador gráfico debes tener algo como esto:
Si todo bien continuemos
5. MyRestFulGP
Como dijimos al principio, esta clase nos permite trabajar con el API REST implementando dos métodos uno para GET y otro para POST, el código es pequeño y esta comentado. Lo importante aquí es indicar en la variable HTTP_EVENT la dirección del apirest.php ya sea en local o internet.
package com.bolivia.restfulgp; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URLEncoder; import java.util.UUID; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.json.JSONException; import org.json.JSONObject; import android.util.Log; public class MyRestFulGP { private final String HTTP_EVENT="http://localhost/api/apirest.php"; private HttpClient httpclient; /** * Envia los datos por GET * @throws IOException * @throws ClientProtocolException * @throws JSONException * */ public String addEventGet(String name, String age) throws ClientProtocolException, IOException, JSONException { httpclient = new DefaultHttpClient(); //los datos a enviar String uuid = UUID.randomUUID().toString(); name = URLEncoder.encode(name,"UTF-8"); age = URLEncoder.encode(age,"UTF-8"); //url, cabecera JSON y ejecuta HttpGet httpget = new HttpGet(HTTP_EVENT + "?name="+name+"&age="+age+"&uuid="+uuid ); httpget.addHeader("Content-Type", "application/json"); HttpResponse response = httpclient.execute(httpget); //obtiene la respuesta del servidor se transforma a objeto JSON String jsonResult = inputStreamToString(response.getEntity().getContent()).toString(); JSONObject object = new JSONObject(jsonResult); Log.i("jsonResult",jsonResult); if( object.getString("Result").equals("200")) { return "Petición GET: Exito"; } return "Petición GET: Fracaso"; } /** * Envia los datos por POST * @throws IOException * @throws ClientProtocolException * @throws JSONException * */ public String addEventPost(String name, String age) throws ClientProtocolException, IOException, JSONException { httpclient = new DefaultHttpClient(); String uuid = UUID.randomUUID().toString(); //url y tipo de contenido HttpPost httppost = new HttpPost(HTTP_EVENT); httppost.addHeader("Content-Type", "application/json"); //forma el JSON y tipo de contenido JSONObject jsonObject = new JSONObject(); jsonObject.put("uuid", uuid ); jsonObject.put("name", name ); jsonObject.put("age", age ); StringEntity stringEntity = new StringEntity( jsonObject.toString()); stringEntity.setContentType( (Header) new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); httppost.setEntity(stringEntity); //ejecuta HttpResponse response = httpclient.execute(httppost); //obtiene la respuesta y transorma a objeto JSON String jsonResult = inputStreamToString(response.getEntity().getContent()).toString(); JSONObject object = new JSONObject(jsonResult); Log.i("jsonResult",jsonResult); if( object.getString("Result").equals("200")) { return "Petición POST: Exito"; } return "Petición POST: Fracaso"; } /** * Transforma el InputStream en un String * @return StringBuilder * */ private StringBuilder inputStreamToString(InputStream is) { String line = ""; StringBuilder stringBuilder = new StringBuilder(); BufferedReader rd = new BufferedReader( new InputStreamReader(is) ); try { while( (line = rd.readLine()) != null ) { stringBuilder.append(line); } } catch( IOException e) { e.printStackTrace(); } return stringBuilder; } }
Vemos que en esta clase, hacemos uso de una variable llamada UUID el cual generamos con randomUUID y tiene la forma de «ecf02d7e-c10a-4904-aad1-1bb294845ac0«, UUID son las siglas en inglés de Identificador Universalmente Único y se usa para que las peticiones que lleguen al servidor, no sean repetidas, esto porque a un api rest le llegan cientos sino es que miles de peticiones y este debe saber como identificarlas para por ejemplo no insertar el mismo registro dos veces. En el ejemplo de este post, no se le esta dando ningún uso, sin embargo hay que tenerlo en cuenta para futuros proyectos.
6. MyAsyncTask
Esta clase que se extiende de AsyncTask nos permite realizar tareas en segundo plano, mostrará un ProgressDialog mientras se realiza la tarea, al terminar pasara el resultado a la interfaz, el resultado es un string.
package com.bolivia.restfulgp; import java.io.IOException; import org.apache.http.client.ClientProtocolException; import org.json.JSONException; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.widget.TextView; public class MyAsyncTask extends AsyncTask<String,Void,String>{ private ProgressDialog progressDialog; private Context context; TextView textView; /**Constructor de clase */ public MyAsyncTask(Context context, TextView textView) { this.context = context; this.textView = textView; } /** * Realiza la tarea en segundo plano * @param params[0] Comando GET/POST * @param params[1] Nombre * @param params[2] Edad * */ @Override protected String doInBackground(String... params) { if( params[1].length()==0 || params[2].length()==0 ) { return "Todos los campos son obligatorios"; } else { MyRestFulGP myRestFulGP = new MyRestFulGP(); try { if( params[0].equals("GET")) { return myRestFulGP.addEventGet(params[1],params[2]); }else if( params[0].equals("POST")) { return myRestFulGP.addEventPost(params[1],params[2]); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } } return ""; } /** * Antes de comenzar la tarea muestra el progressDialog * */ @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = ProgressDialog.show( context, "Por favor espere", "Procesando..."); } /** * Cuando se termina de ejecutar, cierra el progressDialog y retorna el resultado a la interfaz * **/ @Override protected void onPostExecute(String resul) { progressDialog.dismiss(); textView.setText(resul); } }
7. MainActivity
Para terminar implementaremos en el MainActivity el evento CLIC para los botones GET y POST que ejecutaran una instancia del MyAsyncTask para cada una de las peticiones de la siguiente manera:
public class MainActivity extends Activity { Button btnGet; Button btnPost; EditText txtName; EditText txtAge; TextView txtResponse; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnGet = (Button) findViewById( R.id.btnGet ); btnPost = (Button) findViewById( R.id.btnPost ); txtName = (EditText) findViewById( R.id.txtName ); txtAge = (EditText) findViewById( R.id.txtAge ); txtResponse = (TextView) findViewById( R.id.txtResponse ); //Evento para el boton GET btnGet.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { new MyAsyncTask(MainActivity.this, txtResponse) .execute("GET", txtName.getText().toString(), txtAge.getText().toString()); } }); //Evento para el boton POST btnPost.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View view) { new MyAsyncTask(MainActivity.this, txtResponse) .execute("POST", txtName.getText().toString(), txtAge.getText().toString()); } }); }
Ejecuta
Si la petición tuvo éxito te avisara en la interfaz, así tambien las peticiones que se envien tanto por GET como por POST, se almacenaran en un archivo de texto en el servidor con el nombre de log.txt, después de realizar unas cuantas peticiones al apirest, el archivo log tendrá la forma de:
------------------------------------------------------------------------------- GET :: {"name":"Lago Losina","age":"23","uuid":"da29ec34-a45d-4e78-be4d-f0f844815ea2"} ------------------------------------------------------------------------------- POST :: {"age":"65","name":"Subiran Alatorre","uuid":"eeac4133-6ee7-4411-962f-4b8705953d5b"} -------------------------------------------------------------------------------
enjoy!!!
Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.
Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye
Enjoy! :)
Video Tutorial que muestra una de las maneras de utilizar y mostrar imagenes en iReport, pasando estas como parametros d...
Lo que veremos en este post es la configuración del driver para PHP de SQL Server que ha creado Microsoft el cual permit...
¿Que son los archivos JNLP? Java Network Launching Protocol (JNLP) es una especificación usada por Java Web Start. Esta...
En un tutorial anterior se creo un WebServices [Java WebServices] utilizando java y Netbeans, en esta ocasión se da cont...
Realizar pruebas sobre nuestro código nos permiten comprobar su correcto funcionamiento e integración con otros módulos...
NUEVA ESPECIFICACIÓN TÉCNICA DEL CÓDIGO DE CONTROL (Ver.7.0) En el marco del Nuevo Sistema de Facturación implementado p...
Los comentarios estan cerrados
Por lo general se usan transacciones a nivel base de datos y posteriormente se llaman estos a través de procedimientos a...
En este post, aprenderemos como conectar Visual Basic 6 con SQL Server, abrir una tabla, leer su contenido y mostrar est...
Lo que veremos en este post es la configuración del driver para PHP de SQL Server que ha creado Microsoft el cual permit...
Google Bard la inteligencia artificial de Google se actualiza con una mejora que entra a competir con el resto de IAs y...
Hola, muchas gracias por el tutorial está muy bueno y me ha ayudado bastante, ya que soy bastante nuevo en el tema de Android, por lo mismo me ha surgido una duda, te explico lo que estoy haciendo, bueno estoy haciendo una petición desde un Android a un php el cual hace un insert en una tabla que tengo en mysql, con el código que has dado puedo comunicarme y hacer lo que quiero, pero que pasa si la conexión a internet se interrumpe justo cuando en el momento cuando el php a recibido el json y estoy haciendo el insert en mi tabla, como sabrá el Android que el insert se realizó correctamente si no esta conectado si se perdió la comunicación entre ambos?
Gracias.. y insisto muy buen tutorial
Hola, me muestra los resultados del post en blanco en el archivo log.txt y no me muestra el msj. del status en pantalla.