Bluetooth se ha convertido en una tecnología muy popular, especialmente en dispositivos móviles. Es una tecnología para descubrir y transferir datos entre dispositivos cercanos. Prácticamente todos los dispositivos móviles modernos tienen capacidades Bluetooth en estos días. Si desea crear una interfaz de aplicación con otro dispositivo habilitado para Bluetooth, desde teléfonos hasta altavoces, debe saber cómo usar la API Bluetooth de Android..
En este tutorial, crearemos una aplicación similar a la aplicación Bluetooth incorporada en la configuración de Android. Incluirá las siguientes características:
También repasaremos lo básico para conectar y enviar datos a otro dispositivo Bluetooth. He creado un proyecto para comenzar, que puede descargar desde GitHub. La siguiente captura de pantalla ilustra cómo se ve el proyecto inicial. Si te quedas atascado o te encuentras con problemas, puedes echar un vistazo al proyecto finalizado en GitHub..
Antes de poder habilitar Bluetooth en un dispositivo Android, debemos solicitar los permisos necesarios. Hacemos esto en el manifiesto de la aplicación. los BLUETOOTH
el permiso permite que nuestra aplicación se conecte, desconecte y transfiera datos con otro dispositivo Bluetooth. los BLUETOOTH_ADMIN
el permiso permite que nuestra aplicación descubra nuevos dispositivos Bluetooth y cambie la configuración de Bluetooth del dispositivo.
Usaremos el adaptador Bluetooth para interactuar con Bluetooth. Nosotros instanciamos el adaptador en el ListaActividad
clase. Si el adaptador es nulo
, esto significa que Bluetooth no es compatible con el dispositivo y la aplicación no funcionará en el dispositivo actual. Manejamos esta situación mostrando un diálogo de alerta al usuario y saliendo de la aplicación..
@ Anular la anulación protegida onCreate (Bundle savedInstanceState) … BTAdapter = BluetoothAdapter.getDefaultAdapter (); // El teléfono no es compatible con Bluetooth, así que avísele al usuario y salga. if (BTAdapter == null) new AlertDialog.Builder (this) .setTitle ("No compatible") .setMessage ("Su teléfono no es compatible con Bluetooth") .setPositiveButton ("Exit", nuevo DialogInterface.OnClickListener () public void onClick (diálogo DialogInterface, int cuales) System.exit (0);) .setIcon (android.R.drawable.ic_dialog_alert) .show ();
Si Bluetooth está disponible en el dispositivo, debemos habilitarlo. Para habilitar Bluetooth, iniciamos un intento proporcionado por el SDK de Android, BluetoothAdapter.ACTION_REQUEST_ENABLE
. Esto presentará un cuadro de diálogo al usuario y le pedirá permiso para habilitar Bluetooth en el dispositivo.. REQUEST_BLUETOOTH
Es un entero estático que configuramos para identificar la solicitud de actividad..
public class ListActivity extiende ActionBarActivity implementa DeviceListFragment.OnFragmentInteractionListener public static int REQUEST_BLUETOOTH = 1;… void protegido onCreate (Bundle savedInstanceENTINVENTREPACTIVO). startActivityForResult (enableBT, REQUEST_BLUETOOTH);
En este paso, buscamos dispositivos Bluetooth emparejados y los mostramos en una lista. En el contexto de un dispositivo móvil, un dispositivo Bluetooth puede ser:
Es importante saber la diferencia entre un dispositivo Bluetooth emparejado y uno conectado. Los dispositivos emparejados son conscientes de la existencia de cada uno y comparten una clave de enlace, que se puede usar para autenticar, lo que resulta en una conexión. Los dispositivos se emparejan automáticamente una vez que se establece una conexión cifrada.
Los dispositivos conectados comparten un canal RFCOMM, lo que les permite enviar y recibir datos. Un dispositivo puede tener muchos dispositivos emparejados, pero solo se puede conectar a un dispositivo a la vez.
Los dispositivos Bluetooth están representados por la Dispositivo Bluetooth
objeto. Se puede obtener una lista de dispositivos emparejados invocando el getBondedDevices ()
método, que devuelve un conjunto de Dispositivo Bluetooth
objetos. Invocamos el getBondedDevices ()
método en el DeviceListFragment
es onCreate ()
método.
public void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); Log.d ("DEVICELIST", "Super llamado a DeviceListFragment onCreate \ n"); deviceItemList = new ArrayList(); Conjunto pairedDevices = bTAdapter.getBondedDevices ();
Usamos el getName ()
y getAddress ()
Métodos para obtener más información sobre los dispositivos Bluetooth. los getName ()
método devuelve el identificador público del dispositivo mientras que el getAddress ()
El método devuelve la dirección MAC del dispositivo, un identificador que identifica de forma única al dispositivo.
Ahora que tenemos una lista de los dispositivos emparejados, creamos un DeviceItem
objeto para cada Dispositivo Bluetooth
objeto. Luego agregamos cada DeviceItem
objeto a una matriz llamada deviceItemList
. Usaremos esta matriz para mostrar la lista de dispositivos Bluetooth emparejados en nuestra aplicación. El código para mostrar la lista de DeviceItem
Los objetos ya están presentes en el proyecto inicial..
if (pairedDevices.size ()> 0) para (dispositivo BluetoothDevice: pairedDevices) DeviceItem newDevice = new DeviceItem (device.getName (), device.getAddress (), "false"); deviceItemList.add (newDevice);
El siguiente paso es descubrir los dispositivos con los que el dispositivo aún no está emparejado., desconocido dispositivos, y agregarlos a la lista de dispositivos emparejados. Hacemos esto cuando el usuario toca el botón de escaneo. El código para manejar esto se encuentra en DeviceListFragment
.
Primero necesitamos hacer un Receptor de radiodifusión
y anular el onReceive ()
método. los onReceive ()
método se invoca cada vez que se encuentra un dispositivo Bluetooth.
los onReceive ()
El método toma una intención como segundo argumento. Podemos verificar con qué tipo de intención se está transmitiendo invocando getAction ()
. Si la accion es Dispositivo Bluetooth.ACTION_FOUND
, Entonces sabemos que hemos encontrado un dispositivo Bluetooth. Cuando esto ocurre, creamos un DeviceItem
Objeto usando el nombre del dispositivo y la dirección MAC. Finalmente, agregamos el DeviceItem
objetar al ArrayAdapter
para mostrarlo en nuestra aplicación.
clase pública DeviceListFragment extiende Fragment implementa AbsListView.OnItemClickListener … private BroadcastReceiver final bReciever = new BroadcastReceiver () public void onReceive (Contexto de contexto, intención de intento) String action = intent.getAction (); if (BluetoothDevice.ACTION_FOUND.equals (acción)) dispositivo BluetoothDevice = intent.getParcelableExtra (BluetoothDevice.EXTRA_DEVICE); // Crear un nuevo elemento de dispositivo DeviceItem newDevice = new DeviceItem (device.getName (), device.getAddress (), "false"); // Agregarlo a nuestro adaptador mAdapter.add (newDevice); ;
Cuando el botón de escaneo está activado, simplemente necesitamos registrar el receptor que acabamos de hacer e invocar el InicioDescubrimiento ()
método. Si se desactiva el botón de escaneo, anula el registro del receptor e invocamos cancelDiscovery ()
. Tenga en cuenta que el descubrimiento requiere muchos recursos. Si su aplicación se conecta con otro dispositivo Bluetooth, siempre debe cancelar el descubrimiento antes de conectar.
También despejamos el ArrayAdapter
objeto, mAdapter
, cuando comienza el descubrimiento. Cuando comenzamos a escanear, no queremos incluir dispositivos antiguos que ya no estén dentro del alcance del dispositivo.
public View onCreateView (inflador LayoutInflater, contenedor ViewGroup, Bundle savedInstanceState) View view = inflater.inflate (R.layout.fragment_deviceitem_list, container, false); ToggleButton scan = (ToggleButton) view.findViewById (R.id.scan);… scan.setOnCheckedChangeListener (new CompoundButton. En el nombre de la agencia de cambios: Periódico. ; if (isChecked) mAdapter.clear (); getActivity (). registerReceiver (bReciever, filter); bTAdapter.startDiscovery (); else else get (actActivity (). unregisterReceiver (bReciever); bTAdapter.cancelDiscovery ();) );
Eso es. Hemos terminado nuestro escáner Bluetooth..
Las conexiones Bluetooth funcionan como cualquier otra conexión. Hay un servidor y un cliente, que se comunican a través de sockets RFCOMM. En Android, los conectores RFCOMM se representan como un Zócalo bluetooth
objeto. Afortunadamente para nosotros, la mayor parte del código técnico para servidores es manejado por el SDK de Android y está disponible a través de la API de Bluetooth.
Conectarse como cliente es simple. La primera vez que obtenga el zócalo RFCOMM de la Dispositivo Bluetooth
llamando createRfcommSocketToServiceRecord ()
, pasando un UUID, un valor de 128 bits que creas. El UUID es similar a un número de puerto.
Por ejemplo, supongamos que está creando una aplicación de chat que utiliza Bluetooth para chatear con otros usuarios cercanos. Para encontrar otros usuarios con los que chatear, desearía buscar otros dispositivos con su aplicación de chat instalada. Para hacer esto, buscaríamos el UUID en la lista de servicios de los dispositivos cercanos. El uso de un UUID para escuchar y aceptar conexiones Bluetooth agrega automáticamente ese UUID a la lista de servicios del teléfono o al protocolo de descubrimiento de servicios.
Una vez el Zócalo bluetooth
se crea, tu llamas conectar()
sobre el Zócalo bluetooth
. Esto inicializará una conexión con el Dispositivo Bluetooth
a través del zócalo RFCOMM. Una vez que nuestro dispositivo está conectado, podemos usar el zócalo para intercambiar datos con el dispositivo conectado. Hacer esto es similar a cualquier implementación de servidor estándar.
Mantener una conexión Bluetooth es costoso, por lo que debemos cerrar el socket cuando ya no lo necesitemos. Para cerrar el zócalo, llamamos cerrar()
sobre el Zócalo bluetooth
.
El siguiente fragmento de código muestra cómo conectarse con un determinado Dispositivo Bluetooth
:
la clase pública ConnectThread extiende Thread private BluetoothSocket bTSocket; conexión booleana pública (dispositivo Bluetooth bTDevice, UUID mUUID) BluetoothSocket temp = null; intente temp = bTDevice.createRfcommSocketToServiceRecord (mUUID); catch (IOException e) Log.d ("CONNECTTHREAD", "No se pudo crear el socket RFCOMM:" + e.toString ()); falso retorno; prueba bTSocket.connect (); catch (IOException e) Log.d ("CONNECTTHREAD", "No se pudo conectar:" + e.toString ()); prueba bTSocket.close (); catch (IOException close) Log.d ("CONNECTTHREAD", "No se pudo cerrar la conexión:" + e.toString ()); falso retorno; devuelve true; public boolean cancel () try bTSocket.close (); catch (IOException e) Log.d ("CONNECTTHREAD", "No se pudo cerrar la conexión:" + e.toString ()); falso retorno; devuelve true;
Conectarse como servidor es un poco más difícil. Primero, desde tu Adaptador de bluetooth
, debes conseguir un BluetoothServerSocket
, que se utilizará para escuchar una conexión. Esto solo se utiliza para obtener el zócalo RFCOMM compartido de la conexión. Una vez que se establece la conexión, el socket del servidor ya no es necesario y se puede cerrar llamando cerrar()
en eso.
Creamos una instancia de un servidor al llamar listenUsingRfcommWithServiceRecord (nombre de cadena, UUID mUUID)
. Este método toma dos parámetros, un nombre de tipo Cuerda
y un identificador único de tipo UUID
. El parámetro nombre es el nombre que le damos al servicio cuando se agrega a la entrada SDP (Service Discovery Protocol) del teléfono. El identificador único debe coincidir con el UUID que está utilizando el cliente que intenta conectarse.
Entonces llamamos aceptar()
en el recién obtenido BluetoothServerSocket
para esperar una conexión. Cuando el aceptar()
La llamada devuelve algo que no es nulo
, lo asignamos a nuestro Zócalo bluetooth
, que luego podemos utilizar para intercambiar datos con el dispositivo conectado.
El siguiente fragmento de código muestra cómo aceptar una conexión como servidor:
la clase pública ServerConnectThread extiende Thread private BluetoothSocket bTSocket; public ServerConnectThread () public void acceptConnect (BluetoothAdapter bTAdapter, UUID mUUID) BluetoothServerSocket temp = null; intente temp = bTAdapter.listenUsingRfcommWithServiceRecord ("Service_Name", mUUID); catch (IOException e) Log.d ("SERVERCONNECT", "No se pudo obtener un BluetoothServerSocket:" + e.toString ()); while (verdadero) prueba bTSocket = temp.accept (); catch (IOException e) Log.d ("SERVERCONNECT", "No se pudo aceptar una conexión entrante."); descanso; if (bTSocket! = null) try temp.close (); catch (IOException e) Log.d ("SERVERCONNECT", "No se pudo cerrar ServerSocket:" + e.toString ()); rotura; public void closeConnect () try bTSocket.close (); catch (IOException e) Log.d ("SERVERCONNECT", "No se pudo cerrar la conexión:" + e.toString ());
La lectura y escritura de la conexión se realiza mediante streams., Flujo de entrada
y Flujo de salida
. Podemos obtener una referencia a estas corrientes llamando getInputStream ()
y getOutputStream ()
sobre el Zócalo bluetooth
. Para leer y escribir en estas corrientes, llamamos leer()
y escribir()
respectivamente.
El siguiente fragmento de código muestra cómo hacer esto para un solo entero:
la clase pública ManageConnectThread amplía el subproceso public ManageConnectThread () public void sendData (BluetoothSocket socket, int data) lanza IOException ByteArrayOutputStream output = new ByteArrayOutputStream (4); output.write (datos); OutputStream outputStream = socket.getOutputStream (); outputStream.write (output.toByteArray ()); public int receiveData (conector BluetoothSocket) lanza IOException byte [] buffer = new byte [4]; ByteArrayInputStream input = new ByteArrayInputStream (búfer); InputStream inputStream = socket.getInputStream (); inputStream.read (búfer); devolver input.read ();
Puedes encontrar ambos ejemplos en el proyecto terminado en GitHub.
Hemos creado con éxito nuestro propio escáner Bluetooth y hemos aprendido lo siguiente:
Siéntase libre de usar el código en el proyecto terminado en GitHub y modificarlo en sus propias aplicaciones.