curso 14/15 desarrrollo de aplicaciones android...
TRANSCRIPT
Desarrrollo de aplicaciones Android Curso 14/15
Conectividad Bluetooth
Desarrollo de aplicaciones Android 14/15
2 © Grupo Arco
Bluetooth es una tecnología standard abierta, global wireless para
intercambio de datos sobre distancias cortas entre aparatos fijos y
móviles, creado áreas de redes personales (PANs), con altos
niveles de seguridad. El marco de aplicaciones de Android provee
acceso a la funcionalidad Bluetooth a través de la Android
Bluetooth API
4 tareas principales para comunicarse usando Bluetooth
•La configuración de Bluetooth
•Encontrar aparatos que estén o bien ya apareados o que se
encuentre dentro del área local
•Conectar aparatos
•Transferir datos entre aparatos
Desarrollo de aplicaciones Android 14/15
3 © Grupo Arco
Clases e interfaces necesarias (I)
BluetoothAdapter (radio bluetooth)
-Descubrimiento de otros aparatos BT
-Consulta a la lista de aparatos ligados
- Instanciar un BluetoothDevice usando una dirección MAC conocida
- Crear un BluetoothServerSocket para escuchar las conversaciones
de otros equipos
BluetoothDevice Es el equipo remoto con BT. Esta clase se usa para pedir
conexión con un equipo remoto a través de la interfaz BluetoothSocket
BluetoothSocket Punto de conexión para intercambiar datos con otros
equipos BT usando InputStream y OutputStream. Es la interfaz de un
socket BT. La devuelve el BluetoothServerSocket ante un pedido de
conexión cuando la conexión es aceptada
BluetoothServerSocket Representa un servidor socket abierto para
pedidos entrantes. Al comenzar una conexión un aparato debe abrir un
servidor socket
Desarrollo de aplicaciones Android 14/15
4 © Grupo Arco
Clases e interfaces necesarias (II) BluetoothClass (solo lectura) Describe las características y capacidades del
equipo BT
BluetoothProfile: Interfaz que especifica el perfil de la aplicación (Android 3.0)
- Auriculares (BluetoothHeadset) Provee soporte para auriculares para
móviles junto con Hands-Free
- A2DP (Advanced Audio Distribution Profile- BluetoothA2dp) Define como
audio de alta calidad puede ser transmitido entre equipos BT
- Equipos de salud (BluetootHealth a partir de Android 4) Para crear
aplicaciones que se comunican con equipamiento de salud que utilicen BT
(monitores de frecencia cardíaca, medidores de tension arterial, etc)
BluetoothHeathCallback ,
BluetoothHealthAppConfiguration
-Manos libres (Hands-Free)
BluetoothProfile.ServiceListener Interfaz que notifica cuando un cliente ha
sido conectado o desconectado de un servicio con un determinado perfil.
Desarrollo de aplicaciones Android 14/15
5 © Grupo Arco
Permisos Bluetooth
BLUETOOTH: Necesario para realizar cualquier comunicación BT
(pedir o aceptar conexiones, enviar datos)
BLUETOOTH_ADMIN: Necesario para descubrimiento de
equipos o configurar BT
Para aplicaciones que necesiten descubrir y conectar equipos BT
Se declaran en el Manifiesto
<manifest ... > <uses-permission
android:name="android.permission.BLUETOOTH" /> ...
</manifest>
Desarrollo de aplicaciones Android 14/15
6 © Grupo Arco
Pasos para la Conectividad
1)Obtener el adaptador Bluetooth (se llama al método estático getDefaultAdapter())
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
2) Habilitar el adaptador (llamando a startActivityForResult con el intent
ACTION_REQUEST_ENABLE)
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Desarrollo de aplicaciones Android 14/15
7 © Grupo Arco
Pasos para la Conectividad
3) Activando Bluetooth
Búsqueda en el area local de equipos que tengan BT habilitado
Se usa el BluetoothAdapter
El representante del dispositivo (BluetoothAdapter) es un singleton y se obtiene por medio
del método:
BluetoothAdapter.getDefaultAdapter()
Devuelve null si el dispositivo no tiene Bluetooth
Funcionalidad
Iniciar búsquedas de dispositivos
startDiscovery()
Obtener listas de dispositivos ligados
getBondedDevices()
Crear instancias de nuevos dispositivos
getRemoteDevice(String MAC)
Comprobar el estado del Bluetooth
isEnabled(), isDiscovering(), getScanMode()
Desarrollo de aplicaciones Android 14/15
8 © Grupo Arco
Pasos para la Conectividad 3) Activando Bluetooth
private BluetoothAdapter BTAdapter;
Se activa el Bluetooth a través de un intent
if(!BTAdapter.isEnabled())
{
// Lanzamos el Intent que mostrara la interfaz de activacion del
// Bluetooth. La respuesta de este Intent se manejara en el metodo onActivityResult
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Posibles estados. Dependiendo del usuario
Activity.RESULT_OK
Activity.RESULT_CANCELED
Se trata en el método onActivityResult
Desarrollo de aplicaciones Android 14/15
9 © Grupo Arco
Pasos para la Conectividad 4) Haciendo visible al equipo
Si se quiere hacer visible el dispositivo propio a otros equipos hay que llamar a
startActivity con el intent ACTION_REQUEST_DISCOVERABLE Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
• BluetoothAdapter.getScanMode() • Comprobación del estado
• android.bluetooth.SCAN_MODE_CONNECTABLE_DISCOVERABLE • android.bluetooth.SCAN_MODE_CONNECTABLE • android.bluetooth.SCAN_MODE_NONE
• Mediante un Intent • Si no se le indica tiempo (en segundos) lo activa durante 120 segundos
• Como máximo 300 segundos
Desarrollo de aplicaciones Android 14/15
10 © Grupo Arco
Pasos para la Conectividad 5) Detectando Cambios de estado
STATE_CONNECTING: El dispositivo está realizando una conexión
STATE_CONNECTED: El dispositivo tiene una conexión activa
STATE_DISCONNECTING: El dispositivo está finalizando una conexión
STATE_DISCONNECTED: El dispositivo se ha desconectado de una conexión activa
STATE_ON: El Bluetooth está activo
STATE_OFF: El Bluetooth está apagado
STATE_TURNING_ON: El Bluetooth está activándose
STATE_TURNING_OFF: El Bluetooth se está desactivando
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// cuando se encuentra un aparato
if (BluetoothDevice.ACTION_STATE_CHANGED.equals(action))
{
}
Desarrollo de aplicaciones Android 14/15
11 © Grupo Arco
Pasos para la Conectividad 5) Detectando dispositivos
Una vez descubierto se intercambian el nombre, tipo, y la dirección MAC única
Se elige si comunicarse o no
Una vez comunicado por primera vez se hace una peticion de vinculación.
Una vez vinculados las conexiones siguientes se hacen sin necesidad de
descubrimiento.
Estar vinculados no significa estar conectados
Estar conectados significa compartir un canal RFCOMM.
El API de Android requiere estar vinculados antes de generar el canal RFCOMM
Desarrollo de aplicaciones Android 14/15
12 © Grupo Arco
Pasos para la Conectividad 5) Detectando dispositivos ya vinculados
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices if (pairedDevices.size() > 0) { // Loop through paired devices for (BluetoothDevice device : pairedDevices) { // Add the name and address to an array adapter to show in a ListView mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } }
Desarrollo de aplicaciones Android 14/15
13 © Grupo Arco
Pasos para la Conectividad 5) Detectando dispositivos
La aplicación debe registrar un BroadcastReceiver para el intent ACTION_FOUND
// Crear un BroadcastReceiver para ACTION_FOUND
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// cuando se encuentra un aparato
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// obtiene el objeto BluetoothDevice desde el intent
BluetoothDevice device = Intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Agrega el nombre y dirección a un array adapter para mostrarlos en una ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress()); } } };
// Registra el BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
Desarrollo de aplicaciones Android 14/15
14 © Grupo Arco
Pasos para la Conectividad 5) Finalización de la búsqueda
● El sistema informa cuando termina la búsqueda
● Para recibir la notificación es necesario proporcionar
un callback adecuado
● Por medio de un BroadcastReceiver
● Creando un IntentFilter y registrando la implementación del
BroadcastReceiver
● No olvidar unregisterReceiver al finalizar
● Sólo queda lanzar la búsqueda
IntentFilter end; end = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(_finishDiscover, end);
Desarrollo de aplicaciones Android 14/15
15 © Grupo Arco
Pasos para la Conectividad 6) Ejemplo: ScanBTDevices
[…] IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(_receiver, filter); IntentFilter filterEnd = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); registerReceiver(_finishDiscover, filterEnd); […]
[…] _receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (!BluetoothDevice.ACTION_FOUND.equals(action)) return; BluetoothDevice dev = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); […] } […]
unregisterReceiver(_receiver); unregisterReceiver(_finishDiscover);
Desarrollo de aplicaciones Android 14/15
16 © Grupo Arco
Pasos para la Conectividad 6) onDestroy
Como último paso, conviene eliminar el registro a los eventos capturados por el
BroadcastReceiver. Esto se realizará en el método onDestroy() de la actividad.
// Ademas de realizar la destruccion de la actividad, eliminamos el registro del
// BroadcastReceiver.
@Override
public void onDestroy() {
super.onDestroy();
this.unregisterReceiver(bReceiver);
}
Desarrollo de aplicaciones Android 14/15
17 © Grupo Arco
Pasos para la Conectividad 7) Conectando Equipos
● Android sólo proporciona conexiones RFCOMM
● Se encarga de buscar el servicio y conectarse a el
● Es necesario que se especifique el UUID del servicio
RFCOMM
● Universally Unique Identifier
● 128 bits, 32 dígitos hexadecimales, se muestran 8-4-4-4-12
● Ej: “550e8400-e29b-41d4-a716-446655440000”
● Se utiliza la clase BluetoothDevice para obtener un
Socket con el que conectarse al servidor
● createRfcommSocketToServiceRecord()
Desarrollo de aplicaciones Android 14/15
18 © Grupo Arco
Pasos para la Conectividad 7) Conectando Equipos
Implementar mecanismos de ambos lados (clientes y servidor)
Un equipo abre un server socket y el otro , usando la dirección MAC del server inicia
la conexión.
Servidor:
a) Crea unBluetoothServerSocket llamando al
listenUsingRFcommWithServiceRecord(String,UUID)
b)Comienza a escuchar llamando al método accept()
Es bloqueante, hasta una excepción o hasta que el aparato remoto mande un pedido
de conexión con la UUID correspondiente. En este caso el metodo accept() devuelve
BluetoothSocket
c) Si no se aceptan mas conexiones invocar al método close()
Desarrollo de aplicaciones Android 14/15
19 © Grupo Arco
Pasos para la Conectividad 7) Conectando Equipos
Implementar mecanismos de ambos lados (clientes y servidor)
Un equipo abre un server socket y el otro , usando la dirección MAC del server inicia
la conexión.
Cliente
a) Crea unBluetoothSocket llamando al
createRFcommWithServiceRecord(UUID)
b) Inicia la conexión llamando al método socket.connect()
socket.connect chequea el UUID, si coincide con el del serversocket y el
remoto acepta la comunicación, comparten entonces el canal Rfcomm. Es
bloqueante, se realiza con un thread separado del thread principal.
Desarrollo de aplicaciones Android 14/15
20 © Grupo Arco
Pasos para la Conectividad 7) Gestionando la conexión
Una vez conectados comienza el envío de datos
1) Se hace usando las clases InputStream y OutputStream que manejan la
transmisión a través del Socket.
Para obtener y enviar datos se invocan a los métodos getInputStream() y
getOutputStream.
2) Se leen y se escriben datos en los streams usando read(byte[]) y write(byte[])
respectivamente
Desarrollo de aplicaciones Android 14/15
21 © Grupo Arco
Pasos para la Conectividad 7) Cliente: Hilos
● Cuando se intenta recuperar el Socket el dispositivo
se bloquea
● Es una llamada bloqueante
● Se suele utilizar un hilo para evitar que la aplicación
se bloquee
● Nota.- Sólo el hilo principal puede interactuar con la UI
● Handler
● Se pueden utilizar hilos del mismo modo que en Java
● Heredar de Thread
● Implementar Runnable
Desarrollo de aplicaciones Android 14/15
22 © Grupo Arco
Pasos para la Conectividad 7) Cliente: Ejemplo BTClient
● El dispositivo realiza una búsqueda
● Cuando termina muestra los dispositivos encontrados
en una ListView
● Al seleccionar un elemento de la lista
● Se crea un hilo que intenta recuperar la conexión con el
servidor que tiene el UUID:
● “fa87c0d0-afac-11de-8a39-0800200c9a66”
● Si no hay problema envía “Hello world!” al servidor
● En otro caso (el dispositivo no tiene el servicio, etc) al cabo
de un tiempo terminará
Desarrollo de aplicaciones Android 14/15
23 © Grupo Arco
Pasos para la Conectividad 7) Cliente: Ejemplo Servidor
● Necesita que los dispositivos puedan encontrar el
servicio que ofrece
● Debe estar visible
● Debe crear un Socket servidor
● BluetoothAdapter.listenUsingRfcommWithServiceRecord(n
ame, UUID)
● ¡Bloqueante!
● Es necesario crear un hilo para gestionar las peticiones
● Cuando recibe las peticiones actúa en consecuencia
Desarrollo de aplicaciones Android 14/15
24 © Grupo Arco
Pasos para la Conectividad 7) Cliente: Ejemplo BTServer
● Creación del hilo servidor
● Creación de un Handler
● Permite comunicar el hilo servidor con el hilo que gestiona
la UI
● Obtención del BluetoothAdapter
● Activación del Bluetooth
● Visibilidad del Bluetooth
● Una vez visible se activa el hilo servidor
● Al terminar se finaliza el hilo Servidor
Desarrollo de aplicaciones Android 14/15
25 © Grupo Arco
● Ejemplo de conectividad con
bluetooth
Desarrollo de aplicaciones Android 14/15
26 © Grupo Arco
●Conectividad con Bluetooth: Paso 1
● Creación de una aplicación vacía, basada en el
hola mundo, la llamamos BTTest
● Nota, este ejemplo no puede ser ejecutado en
el emulador y se necesitan dos dispositivos con
BT.
Desarrollo de aplicaciones Android 14/15
27 © Grupo Arco
●Paso 2
● El Manifest debe contener los permisos de
BLUETOOTH y BLUETOOTH_ADMIN
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cep.bttest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Desarrollo de aplicaciones Android 14/15
28 © Grupo Arco
●Paso 3: Creación del layout de la MainActivity
● Pondremos 2 botones, uno para hacerse visible y otro
para buscar dispositivos cercanos.
● Pondremos un TextView para indicar el estado de
conección.
● Para mostrar los dispositivos vinculados pondremos
una ListView por encima de los botones.
● Incluiremos controles TextView y EditText para leer y
escribir mensajes a través de la conexión.
● Para ello editamos el res/layout/activity_main.xml
Desarrollo de aplicaciones Android 14/15
29 © Grupo Arco
Primero ponemos el TextView en donde indicaremos el
estado
Luego abrimos un LinearLayout para disponer los dos
botones.
La disposición de los botones en el layout la haremos
horizontales (Buscando dispositivos y Hacerse visible),
usando android.orientation=“horizontal”
Y los otros dos controles listView y textView usando un
nuevo LinearLayout con orientación vertical
Desarrollo de aplicaciones Android 14/15
30 © Grupo Arco
<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"
tools:context=".MainActivity" >
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/Text" />
Ejemplo
<Button
android:id="@+id/Encender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Buscando" />º
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="30dp" >
Desarrollo de aplicaciones Android 14/15
31 © Grupo Arco
<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"
tools:context=".MainActivity" >
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/Text" />
Ejemplo
<Button
android:id="@+id/Encender"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/Buscando" />º
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="30dp" >
Especificar el texto en Res/Values/string.xml
Desarrollo de aplicaciones Android 14/15
32 © Grupo Arco
●Elementos a usar
● Adaptador de Bluetooth: Bluetooh Adapter: permite
iniciar el descubrimiento de dispositivos, preguntar por
la lista de aparatos vinculados, instanciar un
BluetoothDevice usando una dirección MAC y crear
un Socket (BluetoothServerSocket) para hacerse
visible y escuchar el pedido de conexión de otros
aparatos.
● Para obtener un adaptador de BT usamos el método
getDefaultAdapter()
● Creación dinámica: de forma programática
Desarrollo de aplicaciones Android 14/15
33 © Grupo Arco
●Elementos a usar ● BluetoothDevice: Es una clase pública que
representa a un dispositivo Bluetooth remoto. Permite
crear una conexión con el dispositivo o pedir
información del mismo como nombre, dirección,etc.
● BluetoothSocket: Un socket para conectar bluetooth
● Del lado del servidor usar BluetoothServerSocket para
crear un socket server que escucha por pedidos de
conexión. Cuando éste acepta retorna un nuevo
socket BluetoothSocket para controlar la conexión.
● Del lado del cliente, éste usa un socket
BluetoothSocket para ambas cosas, iniciar y controlar
la conexión
● Creación dinámica: de forma programática
Desarrollo de aplicaciones Android 14/15
34 © Grupo Arco
●Elementos a usar
● UUID: Universally Unique Identifier.
● Es un identificador único de 128 bits
Desarrollo de aplicaciones Android 14/15
35 © Grupo Arco
●Paso 4: codificar la aplicación
● En el bttest activity hacer una llamada a una
colección de sub métodos que serán usados
para acceder a los dispositivos bluetooth.
public class Bttest extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Obtener el Bluetooth Adapter
configureBluetooth();
// Configurar la ListView de dispositivos descubiertos
setupListView();
// Configurar el botón de búsqueda de dispositivos
setupSearchButton();
// Configurar el botón de hacerse visible
setupListenButton();
}
Desarrollo de aplicaciones Android 14/15
36 © Grupo Arco
●Paso 4: codificar la aplicación (2)
● Llenar el submétodo configureBluetooth() para
tener acceso al adaptador local. Crear una
variable socket para almacenar socket de
comunicación del cliente o del servidor una vez
que la comunicación ha sido establecida.
Definir un UUID para su aplicación
private BluetoothAdapter bluetooth;
private BluetoothSocket socket;
private UUID uuid = UUID.fromString("a60f35f0-b93a-11de-8a39-12342009c666");
private void configureBluetooth() {
bluetooth = BluetoothAdapter.getDefaultAdapter();
}
Desarrollo de aplicaciones Android 14/15
37 © Grupo Arco
●Paso 5: Crear un método SwitchUI
● Este método será llamado cuando la
comunicación esté establecida para habilitar la
lectura y escritura de mensajes
private void switchUI() {
final TextView messageText = (TextView)findViewById(R.id.text_messages);
final EditText textEntry = (EditText)findViewById(R.id.text_message);
messageText.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);
textEntry.setEnabled(true);
}
Desarrollo de aplicaciones Android 14/15
38 © Grupo Arco
●Paso 6: Llenar el método para hacerse visible
● Este método hace visible al dispositivo local
para que sea descubierto durante un tiempo.
Abre un BluetoothServerSocket para escuchar
los pedidos de conexión de los dispositivos
remotos. Cuando la conexión se hace llama al
método SwitchUI()
Desarrollo de aplicaciones Android 14/15
39 © Grupo Arco
●Paso 6: Llenar el método para hacerse visible(2)
private static int DISCOVERY_REQUEST = 1;
private void setupListenButton() {
Button listenButton = (Button)findViewById(R.id.button_listen);
listenButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Intent disc;
disc = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(disc, DISCOVERY_REQUEST);
}
});
}
Desarrollo de aplicaciones Android 14/15
40 © Grupo Arco
●Paso 6: Llenar el método para hacerse visible(3) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == DISCOVERY_REQUEST) { boolean isDiscoverable = resultCode > 0; if (isDiscoverable) { String name = "bluetoothserver"; try { final BluetoothServerSocket btserver = bluetooth.listenUsingRfcommWithServiceRecord(name, uuid); AsyncTask<Integer, Void, BluetoothSocket> acceptThread = new AsyncTask<Integer, Void, BluetoothSocket>() { @Override protected BluetoothSocket doInBackground(Integer...params) { try { socket = btserver.accept(params[0]*1000); return socket; } catch (IOException e) { Log.d("BLUETOOTH", e.getMessage()); } return null; } @Override protected void onPostExecute(BluetoothSocket result) { if (result != null) switchUI(); } }; acceptThread.execute(resultCode); } catch (IOException e) { Log.d("BLUETOOTH", e.getMessage()); }}}}
Desarrollo de aplicaciones Android 14/15
41 © Grupo Arco
●Paso 7: Código de conexión lado cliente
●Creamos una variable para almacenar el
arrayList de dispositivos encontrados private ArrayList<BluetoothDevice> foundDevices;
●Llenamos el método SetupListView
private ArrayAdapter<BluetoothDevice> aa;
private ListView list;
private void setupListView() {
//Inicializamos el arraylist
if(foundDevices == null)
foundDevices = new ArrayList<BluetoothDevice>();
aa = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1,foundDevices);
list = (ListView)findViewById(R.id.list_discovered);
list.setAdapter(aa);
}
Desarrollo de aplicaciones Android 14/15
42 © Grupo Arco
●Paso 7: Código de conexión lado cliente
●Creamos un BroadcastReceiver que agrega cada
dispositivo encontrado al arrayList creado en el
paso anterior
BroadcastReceiver discoveryResult = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
BluetoothDevice remoteDevice;
remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (bluetooth.getBondedDevices().contains(remoteDevice)) {
foundDevices.add(remoteDevice);
aa.notifyDataSetChanged();
}
}
};
Desarrollo de aplicaciones Android 14/15
43 © Grupo Arco
●Paso 7: Código de conexión lado cliente
●Completamos el método de búsqueda de
dispositivos para iniciar la sesión de búsqueda
private void setupSearchButton() {
Button searchButton = (Button)findViewById(R.id.button_search);
searchButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
registerReceiver(discoveryResult,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
if (!bluetooth.isDiscovering()) {
foundDevices.clear();
bluetooth.startDiscovery();
}
}
});
}
Desarrollo de aplicaciones Android 14/15
44 © Grupo Arco
●Paso 8: Extender el método SetupListView (p.18)
●Agregamos un onItemClickListener para iniciar
una conexión del lado del cliente con el
dispositivo seleccionado. Una vez realizada la
conexión llama al método SwithUI
Desarrollo de aplicaciones Android 14/15
45 © Grupo Arco
●Paso 8: Extender el método SetupListView (p.18)
●Luego de list.setAdapter(aa) agregar
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view,
int index, long arg3) {
AsyncTask<Integer, Void, Void> connectTask = new AsyncTask<Integer, Void, Void>() {
@Override
protected Void doInBackground(Integer...params) {
try {
BluetoothDevice device = foundDevices.get(params[0]);
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
} catch (IOException e) {
Log.d("BLUETOOTH_CLIENT", e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(Void result) {
switchUI();
}
};
connectTask.execute(index);
}
});
Desarrollo de aplicaciones Android 14/15
46 © Grupo Arco
●Paso 9: Probar comunicación
●Ejecutar la aplicación usando dos dispositivos y
probar
Desarrollo de aplicaciones Android 14/15
47 © Grupo Arco
●Paso 10: Intercambiando mensajes
private void switchUI() {
final TextView messageText = (TextView)findViewById(R.id.text_messages);
final EditText textEntry = (EditText)findViewById(R.id.text_message);
messageText.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);
textEntry.setEnabled(true);
textEntry.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
sendMessage(socket, textEntry.getText().toString());
textEntry.setText("");
return true;
}
return false;
}
});
BluetoothSocketListener bsl = new BluetoothSocketListener(socket,
handler, messageText);
Thread messageListener = new Thread(bsl);
messageListener.start();
}
Desarrollo de aplicaciones Android 14/15
48 © Grupo Arco
●Paso 10: Intercambiando mensajes
private void sendMessage(BluetoothSocket socket, String msg) {
OutputStream outStream;
try {
outStream = socket.getOutputStream();
byte[] byteString = (msg + " ").getBytes();
int[] stringAsBytes = null;
stringAsBytes[byteString.length - 1] = 0;
outStream.write(byteString);
} catch (IOException e) {
Log.d("BLUETOOTH_COMMS", e.getMessage());
}
}
Desarrollo de aplicaciones Android 14/15
49 © Grupo Arco
●Paso 10: Intercambiando mensajes
private class MessagePoster implements Runnable {
private TextView textView;
private String message;
public MessagePoster(TextView textView, String message) {
this.textView = textView;
this.message = message;
}
public void run() {
textView.setText(message);
}
}
Desarrollo de aplicaciones Android 14/15
50 © Grupo Arco
●Paso 10: Intercambiando mensajes private class BluetoothSocketListener implements Runnable { private BluetoothSocket socket; private TextView textView; private Handler handler; public BluetoothSocketListener(BluetoothSocket socket, Handler handler, TextView textView) { this.socket = socket; this.textView = textView; this.handler = handler; } public void run() { int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; try { InputStream instream = socket.getInputStream(); int bytesRead = -1; String message = ""; while (true) { message = ""; bytesRead = instream.read(buffer); if (bytesRead != -1) { while ((bytesRead==bufferSize)&&(buffer[bufferSize-1] != 0)) { message = message + new String(buffer, 0, bytesRead); bytesRead = instream.read(buffer); } message = message + new String(buffer, 0, bytesRead-1); handler.post(new MessagePoster(textView, message)); socket.getInputStream(); } } } catch (IOException e) { Log.d("BLUETOOTH_COMMS", e.getMessage()); }}}