You are on page 1of 15

Comunicacin entre Ordenador y dispositivo And...

http://androidesverdesfritos.wordpress.com/2013...

Androides Verdes Fritos


Todo lo que queras saber sobre Android y no te atreviste a preguntar

Comunicacin entre Ordenador y dispositivo


Android mediante el USB
mayo 30, 2013
Bueno, bueno, bueno. Hoy vamos a hacer una aplicacin complicada. Trata servidor, cliente, servicios,
sockets, timer, programacin concurrente y un poco de ingenio. As que abrochaos los cinturones que la
nave va a despegar.
Advertencia: Este tutorial es largo. Pero a m me ha encantado hacerlo.
Vamos a empezar por la aplicacin de escritorio que he realizado en JAVA puro y duro. Pero lo podis
hacer con C, con Python, lo que sea que pueda abrir Socket y llamar a un programa de consola.
Para los que no sepan una buena definicin de qu es un socket, voy a dejar el link de la Wiki que lo
explica, no en mucha profundidad pero servir: http://es.wikipedia.org/wiki/Socket_de_Internet
(http://es.wikipedia.org/wiki/Socket_de_Internet). Una definicin rpida y entendible sera algo como:
un socket es un canal de comunicacin entre dispositivos y es tratado como si fueran ficheros en los que
se escribe o se lee. Este es un esquema de cmo trabajan los socket:

1 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

http://androidesverdesfritos.wordpress.com/2013...

(http://androidesverdesfritos.files.wordpress.com/2013/05/socket_1.png)
En un primero momento pens que lo ms lgico sera que una aplicacin de escritorio que fuera El
servidor que estuviera todo el rato escuchando y que contestara a las peticiones que el dispositivo
hiciera, ya fueran de escritura o de lectura. Pero es el caso de Android, es el dispositivo el que debe ser el
Server Socket. Cambiando mi mtodo de pensamiento, eso es solo la punta del iceberg. Lo divertido fue
hasta que encontr que hay que abrir un puerto TCP de comunicacin mediante el uso del adb. Adb es
2 de 15
16/10/14 10:31
una aplicacin que proporciona el sdk de Android para comunicacin por medio de comandos desde el

Comunicacin entre Ordenador y dispositivo And...

http://androidesverdesfritos.wordpress.com/2013...

ordenador al pc. Se utiliza por ejemplo para abrir un Shell del dispositivo y manejarlo desde nuestro
ordenador.
Esta aplicacin se descarga en el sdk. Normalmente se encuentra en: <ruta_sdk>\platformtools\adb.exe. El comando es:
<ruta_adb>\adb.exe forward tcp:Puerto_elegido tcp: Puerto_elegido

Esto se puede hacer mediante la lnea de comandos o, integrarlo en la aplicacin de escritorio. Para darle
un poco de chicha a la aplicacin lo he hecho as. La imagen de la aplicacin sera la siguiente.

(http://androidesverdesfritos.files.wordpress.com/2013/05/socket_2.png)
El cdigo de la activacin del puerto TCP por medio de JAVA sera:

3 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
4 de 55
15

http://androidesverdesfritos.wordpress.com/2013...

// Esta funcin pertenece al hacer click en el botn de Activar.


private void activatetacpMouseClicked(java.awt.event.MouseEvent evt) {
boolean allok = true;
try {
log.setText("Activando puerto TCP");
//En mi Windows, tengo directamente el sdk en c, por comodidad
Process p = Runtime.getRuntime().exec(
"C:\\android\\adb.exe forward tcp:38300 tcp:38300");
Scanner sc = new Scanner(p.getErrorStream());
if (sc.hasNext()) {
String error = "";
while (sc.hasNext()) {
// Encadenamos todo el mensaje
error += sc.next() + " ";
}
error += ":: No se puede abrir el puente de comunicacion\n"
log.setText(error);
allok = false;
}
} catch (Exception e) {
log.setText(e.getMessage());
allok = false;
} finally {
if (allok) {
log.setText("Todo ha salido bien\n");
} else {
System.out.println("Ha fallado algn proceso\n");
}
}
}
Ahora vamos al envo de los mensajes hacia el terminal Android.
// Formato que le damos a la fecha
private final SimpleDateFormat _dateFormat = new SimpleDateFormat("HH:m
private void sendMessage(String mss) {
try {
// Nos tenemos que conectar a nosotros mismos, el localhost. 38
Socket socket = new Socket("localhost", 38300);
// Creamos el buffer dnde vamos a escribir
BufferedWriter writer = new BufferedWriter(new OutputStreamWrit
// Escribimos en el canal
writer.write(mss, 0, mss.length());
16/10/14 10:31
// Liberamos el buffer

Comunicacin entre Ordenador y dispositivo And...

56
57
58
59
60
61
62
63

http://androidesverdesfritos.wordpress.com/2013...

writer.flush();
// Ya hemos enviado el mensaje, as que lo cerramos
socket.close();
// Creamos la fecha con un formato determinado para incluirlo e
String time = _dateFormat.format(new Date());
// Encadenamos la fecha
log.setText(log.getText() + "Send[" + time + "]" + ":: " + mss
} catch (UnknownHostException e) {
log.setText(log.getText() + "ERROR:: > " + "Socket connection p
+ e.getMessage());
} catch (IOException e) {
log.setText(log.getText() + "ERROR:: > " + "Could not initializ
+ e.getMessage());
}
// Vaciamos de informacin la caja del texto
txtsend.setText("");

}
// Mtodo que se activa cuando se pulsa el botn enviar
private void sendMouseClicked(java.awt.event.MouseEvent evt) {
sendMessage(txtsend.getText());
}

/socket_3.png)

(http://androidesverdesfritos.files.wordpress.com/2013/05

Os dejo al final del blog, el proyecto para que la ejecutis dnde queris y modifiquis a vuestro antojo.
Ahora, pongamos ms situacin. Este es ms o menos el esquema de la aplicacin. Est pensado para
que funcione cuando tengamos el log en pantalla. Se podra mejorar, eso est claro, pero mi idea es la
comunicacin, los Socket, el servicio y la creacin del log en tiempo real.

5 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

/2013/05/socket_4.png)

http://androidesverdesfritos.wordpress.com/2013...

(http://androidesverdesfritos.files.wordpress.com

El cdigo de esa Actividad es:


Nota: si queris informacin sobre Shared preferences tenes esto: http://www.sgoliver.net
/blog/?p=1731 (http://www.sgoliver.net/blog/?p=1731)

6 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
7 de 55
15

http://androidesverdesfritos.wordpress.com/2013...

public class ConfigureService extends Activity {


private CheckBox cb;
private Button gotolog;
private static final String servicioactivado = "myservicio";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.servicio);
// SharedPreferences para guardar el ltimo estado del checkbox
SharedPreferences settings = getSharedPreferences(
"Preferencias_Servicio", MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
gotolog = (Button) findViewById(R.id.txtlog);
cb = (CheckBox) findViewById(R.id.checkBox);
cb.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v) {
// Creacin del intent para ejecutar o finalizar el servicio
Intent servicio = new Intent(getApplicationContext(),
MyService.class);
if (cb.isChecked()) {
Toast.makeText(getApplicationContext(),
"Servicio Activado", Toast.LENGTH_SHORT).show();
PutTextInCheckBox();
getApplicationContext().startService(servicio);
} else {
Toast.makeText(getApplicationContext(),
"Servicio Desactivado", Toast.LENGTH_SHORT).show();
PutTextInCheckBox();
getApplicationContext().stopService(servicio);
}
}
});
// Iniciar el checkbox con los datos adecuados
if (settings.getBoolean(servicioactivado, false))
cb.setChecked(true);
else
cb.setChecked(false);
PutTextInCheckBox();
// Acceso a la actividad del log
gotolog.setOnClickListener(new OnClickListener() {
16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

56
57
58
59
60
61
62
63
64
65
66
67

http://androidesverdesfritos.wordpress.com/2013...

@Override
public void onClick(View v) {
Intent nuevaactividad = new Intent(getApplicationContext(),
MyLog.class);
startActivity(nuevaactividad);
}
});

}
private void PutTextInCheckBox() {
SharedPreferences settings = getSharedPreferences(
"Preferencia Servicio", MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
if (cb.isChecked()) {
cb.setText("Activado");
editor.putBoolean(servicioactivado, true);
gotolog.setVisibility(View.VISIBLE);
} else {
cb.setText("Desactivado");
editor.putBoolean(servicioactivado, false);
gotolog.setVisibility(View.GONE);
}
// No os olvidis de esto.
editor.commit();
}
}

Ahora la clase del servicio:

8 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
9 de 55
15

http://androidesverdesfritos.wordpress.com/2013...

public class MyService extends Service {


public static List<String> buffer;
public static final String TAG = "Mi Servicio";
private Handler mHandler = null;
private ServerSocket server = null;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
// Mtodo para iniciar el servicio
super.onStart(intent, startId);
this.iniciarServicio();
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// Detenemos el servicio
this.finalizarServicio();
}
public void iniciarServicio() {
this.buffer = new ArrayList<String>();
new Thread(initializeConnection).start();
}

private Runnable initializeConnection = new Thread() {


public void run() {
try {
// Creamos un socket servidor.
server = new ServerSocket();
server.setReuseAddress(true);
server.bind(new InetSocketAddress(38300));
while (true) {
// Creamos el socket cliente
Socket client = server.accept();
while (true) {

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

http://androidesverdesfritos.wordpress.com/2013...

// Recogemos el buffer de lectura del cliente


BufferedReader reader = new BufferedReader(
new InputStreamReader(client.getInputStream()));
// La lectura de lnea se puede hacer de varias formas
// Esta es la que ms me gusta, y ms claro veo
String linea = reader.readLine();
// Si la lnea tiene informacin guardamos, sino salimos
// del bucle
if (linea != null) {
// Sincronizamos la variable para que no la escriba ot
// proceso mientras nosotros recogemos.
synchronized (buffer) {
// Aadimos la lnea al buffer que hemos creado,
/ compartido con otra actividad
buffer.add(linea);
}
} else {
break;
}

}
// Cerramos el cliente
client.close();
}
} catch (SocketTimeoutException e) {
Log.e(TAG, "error: " + e.getMessage());
} catch (IOException e) {
Log.e(TAG, "" + e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getLocalizedMessage() + " " + e.getStackTrace()
+ " " + e.toString());
}
}
};

10 de 15

public void finalizarServicio() {


try {
if (server != null)
// Cerramos el socket servidor
server.close();
} catch (IOException ec) {
Log.e(TAG, "Cannot close server socket" + ec);

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

http://androidesverdesfritos.wordpress.com/2013...

}
}
Hay que modificar el manifest.xml:
1

<service android:name="com.example.appandroid.MyService" ></service>

En la actividad del log, deber aparecer cada vez que escribamos algo en el log y demos a enviar la hora
de recepcin y el mensaje. Por cierto, las horas son diferentes por los relojes diferentes del sistema. Uno
lo recoge del ordenador y otro del propio Android. Pero doy fe que se reciben tal cual.

(http://androidesverdesfritos.files.wordpress.com/2013/05/socket_5.png)
Ahora el cdigo de la Actividad:

11 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
12 de
5515

http://androidesverdesfritos.wordpress.com/2013...

public class MyLog extends Activity {


private TextView tv;

@SuppressLint("SimpleDateFormat")
// Para dar formato a la fecha
private final SimpleDateFormat formatofecha = new SimpleDateFormat("HH:m
// Crear un timer es una forma simple para crear un log en tiempo real
private Timer mitimer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_log);
tv = (TextView) findViewById(R.id.txtlog);
}
protected void onDestroy() {
super.onDestroy();
stopTimer();
}
@Override
public void onPause() {
super.onPause();
stopTimer();
}
@Override
public void onResume() {
super.onResume();
startTimer();
}
private void startTimer() {
stopTimer();
mitimer = new Timer();
mitimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
MyLog.this.runOnUiThread(new Runnable() {
public void run() {

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

56
57
58
59
60
61
62
63
64
65
66
67
68

http://androidesverdesfritos.wordpress.com/2013...

// Sincronizamos la variable para que no la escriba otro


// proceso mientras nosotros recogemos.
synchronized (MyService.buffer) {
if (MyService.buffer.size() > 0) {
for (int i = 0; i < MyService.buffer.size(); i++) {
String time = "";
time += formatofecha.format(new Date());
tv.setText(tv.getText() + "\n" + ">> " + time
+ ":: " + MyService.buffer.get(i));
}
// Eliminamos todo lo ledo
MyService.buffer.clear();
}
}
}

});
}
}, new Date(), 333);
}
private void stopTimer() {
if (mitimer != null) {
mitimer.cancel();
mitimer = null;
}
}
}
Por cierto no os olvidis de registrar la actividad del log y dar acceso a internet. El manifest completo
sera:

13 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

http://androidesverdesfritos.wordpress.com/2013...

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android (http:/
package="com.example.appandroid"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.appandroid.ConfigureService"
android:label="@string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"
</intent-filter>
</activity>
<service android:name="com.example.appandroid.MyService" >
</service>
<activity
android:name="com.example.appandroid.MyLog"
android:label="@string/title_activity_my_log" >
</activity>
</application>
</manifest>

Os dejo en un rar, lo siguiente: (https://www.dropbox.com/s/vuwrmjuy0o3k5v3/Socket.rar)


El proyecto NetBeans de la aplicacin cliente.
El proyecto Eclipse de la aplicacin Android.
From Android
Dejar un comentario
Blog de WordPress.com. | El tema Titan.
14 de 15

16/10/14 10:31

Comunicacin entre Ordenador y dispositivo And...

Seguir

http://androidesverdesfritos.wordpress.com/2013...

Seguir Androides Verdes Fritos


Ofrecido por WordPress.com

15 de 15

16/10/14 10:31

You might also like