studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones android bluetooth spp

programacion - Android: cambiar entre dispositivos Bluetooth SPP



manual de programacion android pdf (1)

Ok, después de varios días de probar diferentes soluciones, ahora puedo cambiar entre las impresoras mencionadas. Dado que no estoy del todo seguro de cuál de mis medidas era la razón para tener éxito, voy a enumerarlas todas, por lo que alguien que tropiece con esta publicación tendrá algunas pistas sobre cómo solucionar sus problemas con bluetooth. Sin embargo, estoy seguro de algo: no necesitas diferentes UUID para conectar dos impresoras diferentes: puedes usar el mismo UUID (pero solo tengo uno encendido).

Guardo en caché el dispositivo que se imprimió por última vez, sin embargo, a diferencia de antes, ya no almacenaba en caché el dispositivo Bluetooth real, sino que solo almacenaba en caché su dirección MAC, que se puede obtener a través de:

BluetoothDevice bluetoothDevice; //Obtain BluetoothDevice by looking through paired devices or starting discovery bluetoothDevice.getAddress();

getAddress () devuelve una cadena: la dirección de hardware del dispositivo. Guardo en caché esa dirección MAC y la próxima vez que el usuario quiere imprimir, comparo la dirección mac almacenada en caché con las direcciones MAC de todas las impresoras emparejadas: si la dirección MAC coincide con una de estas, intento conectarme a esa impresora. Si eso falla, restablezco mi dirección mac en caché y trato de buscar otro dispositivo comprobando primero mis dispositivos emparejados si uno de ellos puede conectarse (si puedo conectarme correctamente actualizo mi dirección Mac en caché en consecuencia), y si eso falla, comienzo un descubrimiento bluetooth buscando otros dispositivos potenciales.

Ahora, para no dejar ninguna conexión de socket abierta en una de mis impresoras, mi rutina es la siguiente (dejaré de lado las capturas de prueba que envolví en cada llamada para facilitar la lectura):

Crea el socket

BluetoothSocket btSocket = btDevice.createRfcommSocketToServiceRecord(MY_UUID);

MY_UUID se refiere al conocido UUID utilizado para conectarse a dispositivos SPP:

00001101-0000-1000-8000-00805F9B34FB

Si la creación del socket falla (lo cual es raro y si sucede es muy probable que se deba a permisos insuficientes o que Bluetooth esté deshabilitado / no disponible), no podemos continuar, ya que necesitamos un socket para conectarnos. Por lo tanto, en su bloque catch debe activar el método de desconexión (más sobre esto más adelante).

Conéctese al zócalo creado

bSocket.connect();

Si la conexión falla, no podemos avanzar más, ya que necesitamos una conexión de socket válida para obtener los flujos de entrada y salida. Por lo tanto, en su bloque catch debe activar el método de desconexión (más sobre esto más adelante).

Obtenga la secuencia de entrada y salida

El siguiente paso sería obtener los flujos de entrada y salida del socket. Hago esto en un bucle for que se ejecuta un par de veces (5 veces debería ser suficiente) - en cada iteración compruebo si tengo el flujo de salida, si no, trato de obtenerlo, lo mismo para el flujo de entrada. Al final del ciclo, verifico si tengo mis dos transmisiones, si es así salgo del ciclo (Y todo el método de conexión), si no, procedo con el ciclo y vuelvo a intentarlo. Por lo general, obtengo mis dos transmisiones en la primera iteración de bucle, sin embargo, a veces necesito dos o tres iteraciones para obtener ambas transmisiones.

Si alcanzo el código que sigue después de la declaración del bucle, obviamente no obtuve mis transmisiones o si algo salió mal. En este punto, se considera que la conexión ha fallado y ejecuto mi código de desconexión (que limpia las tomas de corriente y los enchufes abiertos, más sobre esto más adelante).

Leer escribir

Ahora que tiene una conexión con su dispositivo bluetooth objetivo, puede realizar operaciones de lectura y escritura. Una vez que haya terminado, debe realizar una limpieza cerrando todas las secuencias y tomas, más sobre esto en el siguiente párrafo: Desconexión. Recuerde: si se produce una excepción durante las operaciones de lectura / escritura, asegúrese de activar el método de desconexión para limpiar sus recursos. Si su impresora necesita algún tipo de comando de inicialización, asegúrese de enviarlo justo después de conectarse a la impresora y antes de realizar sus operaciones de lectura / escritura.

Desconectando

Por lo general, hay dos ocasiones en las que debe desconectarse:

  • Una vez que haya terminado con sus operaciones de lectura / escritura
  • Si ocurrió una excepción en algún lugar del camino, para limpiar sus recursos

Cierre sus transmisiones

Lo primero que debe hacer es limpiar sus transmisiones, verificar su flujo de entrada y salida, si no son nulas, cerrarlas y establecerlas como nulas. Asegúrese de ajustar cada operación (cerrando el flujo de entrada, cerrando el flujo de salida, etc. ...) en su propio try-catch, ya que de lo contrario no realizaría una limpieza (debido a que se genera una excepción) omitirá todas las demás medidas de limpieza.

Cerrar el zócalo

Ahora que se ha asegurado de que sus flujos de entrada estén limpios, proceda a cerrar su conexión de socket y configúrelo como nulo a partir de entonces.

Una cosa más: tengo un Thread.sleep al principio y al final de mi método de desconexión. El que está al principio tiene aproximadamente 2.5 segundos (= 2500 milisegundos) de largo, el propósito es asegurarse de que no sucede nada más con la impresora (como las operaciones de lectura / escritura pendientes o la impresora sigue imprimiendo, etc.). El segundo Thread.sleep está al final de mi método de desconexión y tiene una duración de 800 milisegundos. El motivo de ese sueño al final está relacionado con los problemas que tuve al tratar de abrir de inmediato un nuevo socket justo después de cerrar uno. Para más detalles, consulte esta respuesta .

¿Preguntas?

En caso de que alguien tenga preguntas relacionadas con mi OP o mi respuesta, hágamelo saber en los comentarios y haré todo lo posible para responderlas.

Tengo dos diferentes impresoras Bluetooth. Bixolon SPP-R200 y Fujitsu FTP-628WSL110. Puedo conectarme a cada uno de ellos por separado (usando un Samsung Galaxy SII) imprimir, desconectar y volver a conectar bien. Sin embargo, si apago el Bixolon y trato de emparejarlo con el Fujitsu (anteriormente sin emparejar, Bixolon aún está sincronizado), falla cuando intento conectarme al socket creado. Lo mismo al revés.

Aquí está el mensaje de error:

07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): Failed to connect to rfcomm socket. 07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): java.io.IOException: Service discovery failed 07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:406) 07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:217) 07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at MyApp.BluetoothConnection.connect(BluetoothConnection.java:171) 07-02 13:00:11.040: E/MyApp.BluetoothConnection(9380): at MyApp.AbstractBluetoothPrinter.connect(AbstractBluetoothPrinter.java:34)

Aquí está el código, que hace que el intento de conexión, la línea que falla bajo las circunstancias explicadas es btSocket.connect (); - excepción ver arriba:

/** Is set in connect() */ private BluetoothSocket btSocket = null; /** Is set prior to connect() */ private BluetoothSocket btDevice; public boolean connect(){ try { btSocket = btDevice.createRfcommSocketToServiceRecord("00001101-0000-1000-8000-00805F9B34FB"); if (btDevice.getName().startsWith("FTP")) { //Special treatment for the fujitsu printer SystemClock.sleep(1000); } } catch (Throwable e) { LogCat.e(TAG, "Failed to create rfcomm socket.", e); return false; } try { // Stop Bluetooth discovery if it''s going on BluetoothHandler.cancelDiscovery(); // This fails under the described circumstances btSocket.connect(); } catch (Throwable e) { LogCat.e(TAG, "Failed to connect to rfcomm socket.", e); return false; } // Obtain streams etc... }

Estoy usando el mismo UUID para conectarme a ambos dispositivos (pero solo un dispositivo está encendido a la vez, nunca están encendidos al mismo tiempo), el conocido UUID de SPP de la API de SDK:

00001101-0000-1000-8000-00805F9B34FB

Lo que me hace preguntarme: ¿Podría ser que necesito un UUID diferente para cada dispositivo? Si es así, ¿alguna idea de cuál?