Especificaciones:
Hardware: LG L9
Versión: ANDROID ICE CREAM 4.0.4
Framework: Eclipse Java EE IDE for Web Developers.
Versión: Juno Service Release 2
Bueno, para comenzar este pequeño tutorial daré algunos
aspectos técnicos que son básicos para entender este tipo de aplicaciones.
Servicios:
Un servicio es un componente de aplicación que puede
realizar operaciones de larga duración dentro de un subproceso y no proporciona
una interfaz de usuarios. Otro componente de la aplicación se puede iniciar
desde un servicio y continuará funcionando dentro un segundo plano, incluso si
el usuario cambia a otra aplicación.
Nuestro servicio puede tener básicamente dos formas:
·
Started
Un servicio se “empieza” cuando
un componente de la aplicación (por ejemplo, una actividad) se inicia llamando startService(). Una vez iniciado, un
servicio puede ejecutarse en un segundo plano de forma indefinida, incluso si
el componente de se inició, se destruye. Por lo general, un servicio que se
inicia realiza solo operación y no devuelve un resultado a la persona que
llama. Por ejemplo, puede descargar o cargar un archivo en la red. Una vez
realizada la operación, el servicio debe pararse.
·
Bound
Un servicio es “bound” cuando un
componente de aplicación se una a ella llamado blindService(). Un servicio
consolidado ofrece una interfaz cliente-servidor que permite a los componentes interactuar
con el servicio, enviar solicitudes, obtener resultados, e incluso hacerlo a
través de los procesos de comunicación entre procesos (IPC). Un servicio
funciona mientras otro componente de la aplicación es obligado a ello.
Múltiples componentes pueden unirse al servicio, pero todos ellos llegan
dirimir, cuando el servicio se destruye.
Aunque generalmente se trabaja con estos servicios por
separado, el servicio puede funcionar en ambos sentidos, se pueden iniciar(ejecutar
indefinidamente) y permitir la unión. Es simplemente cuestión de si se
implementa un par de métodos de devolución de llamada:
Para permitir el inicio de los componentes.
Para permitir la unión.
IntentServices:
Es una clase base para generar un servicio que maneja
peticiones asíncronas ( expresadas como intenciones) a petición.
Los clientes envían peticiones a través de llamadas startService(intención), el servicio se
pone en marcha cuando se necesita, se encarga de cada intención, y todo esto se
genera en un subproceso de trabajo y se detiene a sí mismo cuando se acaba el
trabajo.
Este “proceso en cola
de trabajo” patrón se utiliza comúnmente para no sobrecargar las tareas
dentro del hilo principal dentro la aplicación. En este caso existe la clase
intentService para simplificar este patrón y cuidar los procesos. Para usarlo,
se extiende intentService y se implementa
onHandleIntent(Intención).
IntentService recibirá las intenciones, iniciando el subproceso de trabajo, y
deteniendo el servicio según corresponda.
LA APLICACIÓN
EN JAVA:
clase MyServerSocket.java:
package sockets;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;
/**
*
* @author kamehy
*/
public class MyServerSocket {
final int PUERTO=5001;
ServerSocket sc;
Socket so;
DataOutputStream salida;
String mensajeRecibido;
public void MyServerSocket(){
}
public void initServer() {
try {
boolean listening = true;
sc = new ServerSocket(PUERTO);/* crea socket servidor que escuchara en puerto 5000*/
so = new Socket();
int limite=10;
Random r = new Random();
System.out.println("Iniciando server por puerto " + PUERTO);
while (listening)
new ThreadClienteSc(sc.accept(),r.nextInt(),PUERTO).run();
System.out.println("Cerrando server");
sc.close();//Aqui se cierra la conexión con el cliente
} catch (Exception e) {
System.out.println("Error: " + e.getMessage() + " " + e.toString());
}
}
}
clase Sockets,java:
package sockets;
import java.net.ServerSocket;
import sockets.MyServerSocket;
/**
*
* @author kamehy
*/
public class Sockets {
private static MyServerSocket myserverSocket;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
myserverSocket = new MyServerSocket();
myserverSocket.initServer();
}
}
clase ThreadsClienteSc:
package sockets;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author kamehy
*/
public class ThreadClienteSc implements Runnable{
private int id;
private Socket so;
private DataOutputStream salida;
private String mensajeRecibido;
private int puerto;
public ThreadClienteSc(Socket socket,int Id,int puerto){
this.id = id;
this.puerto = puerto;
this.so = socket;
}
@Override
public void run(){
try {
System.out.println("cliente lanzado:" + id + " puerto:" + puerto);
BufferedReader entrada;
entrada = new BufferedReader(new InputStreamReader(so.getInputStream()));
mensajeRecibido = entrada.readLine();
System.out.println("recibido:" + mensajeRecibido);
salida = new DataOutputStream(so.getOutputStream());
System.out.println("Confirmando conexion al cliente....");
salida.writeUTF("Se recibio tu mensaje.n Terminando conexion..." + id + "\n");
System.out.println("Cerrando conexión..." + id);
} catch (IOException ex) {
System.out.println("error hilo cliente :" + id + ex.toString());
}
}
}
Al correar la aplicación deberá aparecer la siguiente pantalla:
EN ANDROID:
Diseño aplicación:
<RelativeLayout 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: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" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_marginTop="21dp"
android:text="Conexión" />
</RelativeLayout>
clase MainActivity.java:
package com.example.sockets;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnSync = (Button) findViewById(R.id.button1);
btnSync.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
System.out.println("iniciando conexion al server.... pba01");
Intent cliente = new Intent (MainActivity.this, Cliente.class);
startService(cliente);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
clase Cliente.java:
package com.example.sockets;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import android.app.IntentService;
import android.content.Intent;
public class Cliente extends IntentService {
Socket sc;
public Cliente(){
super("IntentServiceOperacion");
}
protected void onHandleIntent(Intent intent){
try {
BufferedReader entrada;
System.out.println("Conectar por puerto:" );
//En esta parte entra en CMD y escribe ipconfig para encontrar la ip de tú PC
//la ip siempre deberá de ser STRING
sc = new Socket("X.X.X.X" , 5001 );
sc.setSoTimeout(10000);
if(sc.isConnected()){
System.out.println("Confirmando conexion al server....");
DataOutputStream mensaje = new DataOutputStream(sc.getOutputStream());
mensaje.writeUTF("ID : 1 | android\n");
entrada = new BufferedReader(new InputStreamReader(sc.getInputStream()));
String mensajeRecibido = entrada.readLine();
System.out.println(mensajeRecibido);
System.out.println("fin conexion al server....");
sc.close();
}
} catch (Exception ex) {
System.out.println("Error al conectar cliente" + ex.toString());
}finally{
if(sc!=null){
try {
sc.close();
} catch (Exception ex) {
System.out.println("Error al cerrar el socket");
}
}
}
}
}
clase AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sockets"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<service android:name="com.example.sockets.Cliente"></service>
<activity
android:name="com.example.sockets.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Al correar la aplicación dentro de un dispositivo android deberá aparecer la siguiente pantalla:
Y al presionar la pantalla deberá de aparecer lo siguiente dentro del aplicativo en java, el cual debimos de ejecutar antes de seleccionar el boton conexión en el dispositivo android:
Nota: Si presentan un error con el puerto 5001, tendrán que desactivar su FIREWALL para que se pueda generar la conexión.
Por: Alejandro Bautista Mancilla y Jhonatan Becerril Bautista
Fuentes: