Continuando con estos post de Cliente/Servidor, en esta oportunidad realizaremos un ejemplo usando un dispositivo móvil conectado a una red local a través de WiFi.
¿Que necesitamos?
Si bien podemos usar el emulador de Android Studio para realizar las pruebas, el objetivo de esta práctica es poder apreciar de manera real la interacción entre diferentes dispositivos como son una PC y un Movil.
El código de nuestro servidor esta en lenguaje java, no lo volveremos a escribir, ya lo tenemos listo de un proyecto anterior [Ejemplo socket java Cliente/Servidor], si no lo tienes, descarga y abre con Netbeans.
Si recordamos, nuestro sistema consistía en un cliente que enviaba peticiones al servidor («frase»,»libro») y el servidor retornaba la respuesta. En esta caso, el sistema no cambia, solo migramos el cliente de una PC a un dispositivo movil.
Tiempo 20 minutos
Nivel: Intermedio
EL CLIENTE
Paso 1. El Proyecto
Crea un nuevo proyecto en Android Studio con el nombre de «ClienteAndroid«, como se ve a continuación.
Paso 2: Permisos
Abre el archivo AndroidManifest.xml y agrega el siguiente permiso:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Paso 3: Interfaz
Reemplaza el contenido de activity_main.xml por:
<?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: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="net.jc_mouse.clienteandroid.MainActivity"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Ingrese petición" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Enviar petición" android:id="@+id/button" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Respuesta del servidor" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textMultiLine" android:ems="10" android:id="@+id/editText2" /> </LinearLayout>
esto nos creara la siguiente interfaz:
Paso 4. El Código del Cliente
Abre el archivo MainActivity.java
Reemplaza los imports por:
import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; 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.Toast; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;
Declara antes del oncreate los controles de la interfaz, el puerto por el cual nos conectaremos (puerto 5000) y la IP del servidor.
/** * Controles * */ private Button button; private EditText editText; private EditText editText2; private Context context = this; /** * Puerto * */ private static final int SERVERPORT = 5000; /** * HOST * */ private static final String ADDRESS = "192.168.x.x";
Para conectarnos con el servidor, usaremos un hilo a parte del hilo principal de la aplicación, para hacer esto contamos con la clase AsyncTask, esta clase la heredaremos en una nueva llamada MyATaskCliente, el código de la clase es el siguiente:
/** * Clase para interactuar con el servidor * */ class MyATaskCliente extends AsyncTask<String,Void,String>{ /** * Ventana que bloqueara la pantalla del movil hasta recibir respuesta del servidor * */ ProgressDialog progressDialog; /** * muestra una ventana emergente * */ @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = new ProgressDialog(context); progressDialog.setCanceledOnTouchOutside(false); progressDialog.setTitle("Connecting to server"); progressDialog.setMessage("Please wait..."); progressDialog.show(); } /** * Se conecta al servidor y trata resultado * */ @Override protected String doInBackground(String... values){ try { //Se conecta al servidor InetAddress serverAddr = InetAddress.getByName(ADDRESS); Log.i("I/TCP Client", "Connecting..."); Socket socket = new Socket(serverAddr, SERVERPORT); Log.i("I/TCP Client", "Connected to server"); //envia peticion de cliente Log.i("I/TCP Client", "Send data to server"); PrintStream output = new PrintStream(socket.getOutputStream()); String request = values[0]; output.println(request); //recibe respuesta del servidor y formatea a String Log.i("I/TCP Client", "Received data to server"); InputStream stream = socket.getInputStream(); byte[] lenBytes = new byte[256]; stream.read(lenBytes,0,256); String received = new String(lenBytes,"UTF-8").trim(); Log.i("I/TCP Client", "Received " + received); Log.i("I/TCP Client", ""); //cierra conexion socket.close(); return received; }catch (UnknownHostException ex) { Log.e("E/TCP Client", "" + ex.getMessage()); return ex.getMessage(); } catch (IOException ex) { Log.e("E/TCP Client", "" + ex.getMessage()); return ex.getMessage(); } } /** * Oculta ventana emergente y muestra resultado en pantalla * */ @Override protected void onPostExecute(String value){ progressDialog.dismiss(); editText2.setText(value); } }
Esta clase NO ira en un archivo aparte, sino en el mismo archivo de MainActivity.
Para terminar, implementaremos la clase anterior en onCreate
button = ((Button) findViewById(R.id.button)); editText = ((EditText) findViewById(R.id.editText)); editText2 = ((EditText) findViewById(R.id.editText2)); button.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { if(editText.getText().toString().length()>0){ MyATaskCliente myATaskYW = new MyATaskCliente(); myATaskYW.execute(editText.getText().toString()); }else{ Toast.makeText(context, "Escriba \"frase\" o \"libro\" ", Toast.LENGTH_LONG).show(); } } });
El código completo de la clase MainActivity es:
package net.jc_mouse.clienteandroid; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; 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.Toast; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class MainActivity extends AppCompatActivity { /** * Controles * */ private Button button; private EditText editText; private EditText editText2; private Context context = this; /** * Puerto * */ private static final int SERVERPORT = 5000; /** * HOST * */ private static final String ADDRESS = "192.168.x.x"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = ((Button) findViewById(R.id.button)); editText = ((EditText) findViewById(R.id.editText)); editText2 = ((EditText) findViewById(R.id.editText2)); button.setOnClickListener( new View.OnClickListener() { public void onClick(View view) { if(editText.getText().toString().length()>0){ MyATaskCliente myATaskYW = new MyATaskCliente(); myATaskYW.execute(editText.getText().toString()); }else{ Toast.makeText(context, "Escriba \"frase\" o \"libro\" ", Toast.LENGTH_LONG).show(); } } }); }//end:onCreate /** * Clase para interactuar con el servidor * */ class MyATaskCliente extends AsyncTask<String,Void,String>{ /** * Ventana que bloqueara la pantalla del movil hasta recibir respuesta del servidor * */ ProgressDialog progressDialog; /** * muestra una ventana emergente * */ @Override protected void onPreExecute() { super.onPreExecute(); progressDialog = new ProgressDialog(context); progressDialog.setCanceledOnTouchOutside(false); progressDialog.setTitle("Connecting to server"); progressDialog.setMessage("Please wait..."); progressDialog.show(); } /** * Se conecta al servidor y trata resultado * */ @Override protected String doInBackground(String... values){ try { //Se conecta al servidor InetAddress serverAddr = InetAddress.getByName(ADDRESS); Log.i("I/TCP Client", "Connecting..."); Socket socket = new Socket(serverAddr, SERVERPORT); Log.i("I/TCP Client", "Connected to server"); //envia peticion de cliente Log.i("I/TCP Client", "Send data to server"); PrintStream output = new PrintStream(socket.getOutputStream()); String request = values[0]; output.println(request); //recibe respuesta del servidor y formatea a String Log.i("I/TCP Client", "Received data to server"); InputStream stream = socket.getInputStream(); byte[] lenBytes = new byte[256]; stream.read(lenBytes,0,256); String received = new String(lenBytes,"UTF-8").trim(); Log.i("I/TCP Client", "Received " + received); Log.i("I/TCP Client", ""); //cierra conexion socket.close(); return received; }catch (UnknownHostException ex) { Log.e("E/TCP Client", "" + ex.getMessage()); return ex.getMessage(); } catch (IOException ex) { Log.e("E/TCP Client", "" + ex.getMessage()); return ex.getMessage(); } } /** * Oculta ventana emergente y muestra resultado en pantalla * */ @Override protected void onPostExecute(String value){ progressDialog.dismiss(); editText2.setText(value); } } }
Paso 5. Prueba el proyecto
La mayoría de los celulares inteligentes cuenta con la opción de «Vinculación y zona Wi-Fi portátil«, activa y conecta tu PC a la red.
A continuación compila el proyecto y ejecuta en tu dispositivo móvil.
No te olvides de ejecutar el servidor.
Ya puedes presionar el botón para conectarse al servidor, la respuesta sera instantánea a menos que tu PC este muy ocupado.
En El siguiente video puedes ver la ejecución del servidor y del celular.
enjoy!!!!
Geany es un editor de texto para Sistemas Operativos Linux, windows y MAC que utiliza el kit de herramientas GTK+ con ca[...]
¿Qué es una vista? Una vista (View) o Tabla Virtual, es una forma lógica de ver los datos ubicados en varias tablas, es[...]
Cuando se almacenan imágenes en una aplicación java y se desea después a modo de registro buscar estas y cargarlas en al[...]
Tercera parte del tutorial [Crea tu blog con el patrón MVC y php] En este post trabajaremos en el Theme del blog, agrega[...]
Un Tile o azulejo, es una parte seccionada de una imagen, por ejemplo la imagen de abajo (chica anime) esta dividida en[...]
En esta tercera parte del tutorial crearemos la interfaz de usuario GUI (VISTA) para el sistema de gestión de stock. Tom[...]