Vous êtes sur la page 1sur 11

Programacion Movil ( Android )

2015

CONECTIVIDAD:
SOCKETS:
Antes de definir lo que es un socket es necesario definir la arquitectura con la que trabajan
dichos Sockets, dicha arquitectura la conocemos como Arquitectura CLIENTE-SERVIDOR.
ARQUITECTURA CLIENTE-SERVIDOR
Esta arquitectura se caracteriza por descomponer el trabajo en dos partes (es decir dos
programas), el servidor que centraliza el servicio y el cliente que controla la interaccin con
el usuario, es en este punto donde el servidor ofrece el servicio a travs de una direccin
conocida, dentro de una red local o global como lo es internet, en este ltimo caso la direccin
conocida seria el nombre del dominio.
Algunos ejemplos de aplicaciones basadas en arquitecturas cliente-servidor, serian:

El chat de Facebook
El correo electrnico
La solicitud de una pgina en internet como el buscador de Google

METODOLOGIA DE TRABAJO

1.- Conectado a la espera de un cliente


2.- Recibe la solicitud generada por el Cte
3.- Se establece la conexion
4.- Responde la solicitud
5.- Cierra la conexion
6.- Cierra la conexion

1.- Se conecta al sevidor


2.- Solicita informacion al servidor
3.- Recibe la respuesta
4.- Cierra la conexion

QUE ES UN SOCKET:
En el desarrollo de aplicaciones, muchas veces nos vamos a ver en la necesidad de intercambiar
informacin entre las aplicaciones que hacemos, para poder llevar a cabo esto haremos uso de esta
herramienta de desarrollo.
Un Socket(enchufe) es un mecanismo de comunicacin entre programas a travs de una red TCP/IP,
dado que en un mismo dispositivo podemos estar ejecutando de forma simultanea diferentes
aplicaciones, es necesario poder identificar cada socket residente en el dispositivo con una
identificar nico.
Para lograr esto cada socket tendr una direccin IP que es la direccin del dispositivo en la
red donde trabaja, ms un puerto. Algunos puertos conocidos son 80/8080 para el protocolo de
internet HTTP.

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

SOCKETS STREAM (TCP):


Este tipo de sockets ofrecen un servicio orientado a conexin, donde los datos se transfieren
como un flujo continuo, sin empaquetarlos en registro o bloques, este tipo de sockets estn
basados en el protocolo TCP, precisamente es un protocolo orientado a conexin.
A qu se refiere con orientado a conexin?; Significa que para poder intercambiar datos es
necesario primero establecer una conexin entre los dos sockets. Dicho protocolo incorpora la
revisin de errores, ya que en caso de que se detecte que la informacin no llego correctamente
a su destino, esta volver a ser retransmitida, adems no se limita el tamao mximo de informacin
a enviar.
EJERCICIO
Para probar el uso de los sockets implementemos una aplicacin Servidor(Netbeans) y una aplicacin
cliente(Eclipse) donde se cumpla con los siguientes requerimientos:
Servidor Netbeans:
Deber aceptar y mostrar mensajes en consola de cualquier nmero de clientes Android.
Cliente Android:
Implemente una interfaz de usuario similar a la que se muestra en la imagen
La interfaz presentara un ScrollView para poder visualizar los mensajes que sobre pasen la
pantalla.
<EditText
android:id="@+id/edtmsj"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Introduce el mensaje"/>
<Button
android:id="@+id/btnenviar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enviar Mensaje"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/txtmsjs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</ScrollView>

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

SERVIDOR EN NETBEANS
En el siguiente cdigo implementaremos un servidor al que se podr conectar nuestra
aplicacin (cliente) desarrollada en Android, para lo cual deber crear una nueva
aplicacin en NetBeans o Eclipse con el siguiente codigo.

package server_socket;
import java.net.*;
import java.io.*;
public class Server_Socket {
public static void main(String[] args) {
Socket cliente;
// Declaramos el socket del cliente
int noCte = 0;
ServerSocket servidor;
// Declaramos el socket del servidor
try
{
servidor = new ServerSocket(5000);
// Instanciamos el socket del
do
// servidor estableciendo el puerto donde se
{
// hara la conexion y las solicitudes
noCte++;
cliente = servidor.accept();
// Cuando llega un socket cte
System.out.println("Llega el cliente:"+noCte);
BufferedReader entrada = new BufferedReader( new InputStreamReader(cliente.getInputStream()));
// Imprimimos en consola el mensaje
System.out.println( entrada.readLine() );
// Definimos el flujo escritura con el cliente instanciado
PrintStream ps = new PrintStream(cliente.getOutputStream());
// Mandamos un mensaje al cliente en el flujo de datos
ps.println("Usted es mi cliente"+noCte);
cliente.close();
}while(true);
// El servidor se mantendra disponible
}
catch( Exception e )
{
e.printStackTrace();
}

// Manejamos las excepciones que se generen


// Imprimimos la pila de llamadas

}
}

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

CLIENTE EN ANDROID
En el siguiente cdigo implementaremos nuestro cliente en Android el cual se conectara a
nuestro servidor elaborado anteriormente.
public static class PlaceholderFragment extends Fragment implements OnClickListener{
EditText edtmsj;
Button btnenviar;
TextView txtmsjs;
public PlaceholderFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_socket, container, false);
edtmsj = (EditText) rootView.findViewById(R.id.edtmsj);
btnenviar = (Button) rootView.findViewById(R.id.btnenviar);
btnenviar.setOnClickListener(this);
txtmsjs = (TextView) rootView.findViewById(R.id.txtmsjs);
return rootView;
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new Conexion().enviar();
}
class Conexion
{
Socket socketCTE;
public void enviar()
{
String ip = "192.168.43.105";
int puerto = 5000;
try
{
socketCTE = new Socket(ip,puerto);
PrintWriter salida = new PrintWriter(new
OutputStreamWriter(socketCTE.getOutputStream()),true);
log("Yo Digo:");
log(edtmsj.getText().toString());
salida.println(edtmsj.getText().toString());
BufferedReader entrada = new BufferedReader(new
InputStreamReader(socketCTE.getInputStream()));
log("Servidor Dice:");
log(entrada.readLine());
socketCTE.close();
}

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

catch(Exception e)
{
log(e.toString());
}
}
public void log(String msj)
{
txtmsjs.append(msj+"\n");
}
}
}
Como en este caso estamos intentando acceder a la red, debemos dar el permiso siguiente a
nuestra aplicacin para que pueda comunicarse, considere tambin que puede ser necesario
desactivar o incluir las excepciones necesarias en el Firewall para asegurar el xito de la
aplicacin, el permiso entonces seria el siguiente:
<uses-permission android:name="android.permission.INTERNET"/>
Una vez que se haya probado la apliacion y se hayan enviado mensajes al servidor, en la consola
del mismo se vern algo similar a la siguiente imagen:

Una vez que ya conocio el uso de los sockets en Android, ahora podr implementarlos en sus
aplicaciones para conectarlos con cualquier tecnologa, ya sea para sincronizar los datos de
una base de datos de una aplicacin con una base de datos alojada en un servidor, entre muchas
otras funcionalidades.

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

CONSUMIR WEB SERVICE REST


Para la elaboracin de esta practica, previamente se ha elaborado un web service utilizando
RESTFUL teniendo como servidor GlassFish en Netbeans esto para poder acceder a una tabla Clientes
de una base de datos determinada, la imagen que se muestra a continuacin representa el web
service desplegado y funcionando correctamente:

Para poder consumir nuestro web service, tenemos varias alternativas, ya sea en una aplicacin
de escritorio, desde una pagina web pero en nuestro caso lo consumiremos desde una aplicacin
mvil, especficamente en Android.
Para comenzar reutilizaremos la aplicacin que hemos
estado realizando para insetar clientes, en este momento
nuestra aplicacin realiza la insercin a de los clientes
tanto en una base de datos como en una archivo te texto.
La nica modificacin que haremos sobre nuestra
aplicacin ser agregar un nuevo botn de guardar en la
parte inferior con el texto Guardar WS en seguida se
muestra el cdigo que se deber agregar en el cdigo XML.
<Button
android:id="@+id/btnguardarws"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=":: Guardar WS::"
/>
Agregaremos tambin un nuevo Item al menu, esta opcin se
utilizara para hacer la visualizacin de los clientes que
estn almacenados en la base de datos del servidor.
<item
android:id="@+id/itmverctesws"
android:orderInCategory="100"
android:title="Ctes WS"
app:showAsAction="always"/>

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

Lo anterior nos obliga entonces a declarar otro objeto dentro de la clase PlaceholderFragment
del archivo Clientes.java de tipo Button tal como se muestra a continuacin:
Button btnguardar, btnguardartxt, btnguardarws;
Y dentro del mtodo onCreateView, asociar dicho objeto con la vista declarada en el XML, asi como
asociarle el escuchador de eventos como se muestra enseguida.
btnguardarws = (Button) rootView.findViewById(R.id.btnguardarws);
btnguardarws.setOnClickListener(this);
Ahora bien antes de colocar el cdigo que se ejecutara en el mtodo onClick veamos que tendremos
que hacer para poder insertar el cliente en nuestra base de datos remota.
INSERTAR UN CLIENTE
Para poder realizar la insercin y primero la conexin de la aplicacin con el Web Service,
tendremos que utilizar la siguiente direccin a donde haremos la peticin de insercin de datos,
esta direccin es la siguiente:
http://localhost:8080/WSCurso1/webresources/ws.curso.android.clientes
Para ubicar esta direccin tendremos que ubicar en el navegador donde se desplego el Web Service,
y dar click sobre la tabla, esto nos dara algo similar a la siguiente ventana:

Para poder hacer la insercin utilizaremos la peticin POST, y en dicha peticin deberemos incluir
un objeto JSON que contenga los datos del cliente que queremos insertar, el formato JSON ser
similar al siguiente:
{nombre:Rubensin,direccion:mi casa,sexo:M,estado:Guanajuato,}
Es importante recordar que a partir de la versin 3 de Android, no es permitido ejecutar
operaciones de ejecucin prolongada sobre el hilo principal para lo cual ser necesario utilizar
una tarea asncrona que ejecuta de forma paralela al hilo principal nuestra tarea de insercin:
Nuestra tarea asncrona quedara implementada entonces de la siguiente manera, hay que indicar
que la clase que hereda de AsyncTask debera estar en un archivo diferente dentro del paquete
principal.

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

public class InsCliente extends AsyncTask<String, Void, Void> {


boolean ban = true;
ProgressDialog dialogo;
Activity act;
public InsCliente( Activity act )
{
this.act = act;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dialogo = new ProgressDialog(act);
dialogo.setMessage("Insertando Cliente..");
dialogo.show();
}
@Override
protected Void doInBackground(String... valores) {
HttpClient objHttp = new DefaultHttpClient();
try
{
HttpPost objPost = new
HttpPost("http://192.168.43.105:8080/WSCurso1/webresources/ws.curso.android
.clientes");
objPost.setHeader("Accept","application/json");
objPost.setHeader("content-type","application/json");
JSONObject datos = new JSONObject();
datos.put("idcte",0);
datos.put("nombre", valores[0]);
datos.put("direccion", valores[1]);
datos.put("sexo",valores[2]);
datos.put("idedo", 1);
datos.put("edad", Integer.parseInt(valores[4]));
datos.put("telefono", valores[5]);
datos.put("email", valores[6]);
StringEntity objEntity = new StringEntity(datos.toString());
objPost.setEntity(objEntity);
HttpResponse res = objHttp.execute(objPost);
String respWS = EntityUtils.toString(res.getEntity());
if( !respWS.equals("true"))
ban = false;
}
catch(Exception e)
{

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

Log.e("Web Service Error", "Error en el WS"+e.toString());


ban = false;
}
finally
{
objHttp.getConnectionManager().shutdown();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialogo.dismiss();
}
}
Como en nuestra aplicacin estamos haciendo peticiones HTTP, es decir intentando acceder via
internet a un servidor remoto, es necesario dar ese permiso a nuestra aplicacin, sino hacemos
esto nuestra aplicacin lanzara un error, para evitar esto bastara con colocar el siguiente
permiso en el archivo AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
Hecho lo anterior no indica que ya hayamos terminado y que nuestra aplicacin guardar los datos
ingresados en la misma, pues no hemos ejecutado o mandado llamar nuestra tarea asincrona, para
ejecutarla tendremos que modificar el mtodo onClick como se muestra en seguida.

int idedo = 0;
switch( v.getId() )
{
case R.id.btnguardar:
String[] args = new String[] {edo};
Cursor c = BD.rawQuery("SELECT * FROM estados WHERE nomedo = ?", args);
if( c.moveToFirst() )
idedo = c.getInt(0);
String Qry = "INSERT INTO
clientes(nombre,direccion,sexo,idedo,edad,telefono,email)
VALUES('"+nom+"','"+dir+"','"+sex+"',"+idedo+","+Integer.parseInt(eda)+",'"+tel+"'
,'"+email+"')";
BD.execSQL(Qry);
Toast.makeText(getActivity(), "Cliente Insertado", Toast.LENGTH_SHORT).show();
break;
case R.id.btnguardartxt:
ClientesTXT objCteTxt = new ClientesTXT(getActivity());
objCteTxt.insertar(nom+" "+edo);
break;
case R.id.btnguardarws:
new
InsCliente(getActivity()).execute(edtnom.getText().toString(),edtdir.getText().toS

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

tring(),sex+"",spnedo.getSelectedItem().toString(),edtedad.getText().toString(),ed
ttel.getText().toString(),edtmail.getText().toString());
}

En el caso de la opcin guardar observara que al ejecutar la tarea asncrona le pasamos cada uno
de los valores que obtenemos de las vistas que forman nuestra interfaz.
DESPLEGAR LOS CLIENTES
Para finalizar nuestra prctica solo nos resta por visualizar los clientes que se han insertado
en nuestra base de datos remota, y para eso volveremos a utilizar nuestro archivo XML que usamos
cuando desplegamos los clientes almacenados en la base de datos asi como los que almacenamos en
el archivo.
El paso siguiente a realizar ser generar una nueva actividad que consuma nuestro web service y
nos consulte la base de datos para posteriormente llenar nuestra lista mediante el adaptador.
Cabe recalcar que para el llenado de dicho adaptador es necesario consumir nuevamente nuestro
Web Service, pero ahora usando una peticin GET.
La clase deber estar en un archivo separado con el nombre ListaWS.java donde se definir como
se indica a continuacion:
public class ListaWS extends Activity {
ListView ltvclientes;
ArrayAdapter<String> modelo;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.listactes);
ltvclientes = (ListView) findViewById(R.id.ltvctes);
modelo = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
new ConsCtes().execute();
}
class ConsCtes extends AsyncTask<Void, Void, Boolean>
{
ProgressDialog dialogo;
Boolean ban = true;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialogo = new ProgressDialog(ListaWS.this);
dialogo.setMessage("Procesando Solicitud");
dialogo.show();
}
@Override
protected Boolean doInBackground(Void... arg0) {

Isc. Rubn Torres Fras (isctorres@gmail.com)

Programacion Movil ( Android )

2015

// Creamos el objeto que hace la conexion


HttpClient objHttp = new DefaultHttpClient();
//Creamos el objeto que establece la peticion necesaria sobre el URL de
nuestro WS
HttpGet objGet = new
HttpGet("http://192.168.43.105:8080/WSCurso1/webresources/ws.curso.android.
clientes");
//Establecemos el contenido de la peticion, en este caso sera un JSON
objGet.setHeader("content-type","application/json");
try
{
HttpResponse res = objHttp.execute(objGet);
String respWS = EntityUtils.toString(res.getEntity());
JSONArray respJSON = new JSONArray(respWS);
for(int i=0; i<respJSON.length(); i++)
{
JSONObject objJSON = respJSON.getJSONObject(i);
modelo.add(objJSON.getString("nombre"));
}
}
catch(Exception e)
{
Log.e("Web Service Error", "Error en el WS"+e.toString());
ban = false;
}
return ban;
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialogo.dismiss();
ltvclientes.setAdapter(modelo);
}
}
}

No olvide dar de alta la actividad dentro del archivo AndroidManifest.xml.


<activity android:name="ListaWS" android:label="Lista de Clientes"></activity>
Por ultimo en el archivo Clientes.java, en el mtodo onOptionsItemSelected tendremos que llamar
la actividad, validando que sea en la opcin correcta.
case R.id.itmverctesws:
Intent intlistaws = new Intent(getApplicationContext(),ListaWS.class);
startActivity(intlistaws);

Isc. Rubn Torres Fras (isctorres@gmail.com)