Utilice una impresora bluetooth portátil con android
Tengo una impresora Handheld del bluetooth que puedo comunicar a usar una conexión del SPP de mi Mac (usando Coolterm). Cuando estoy tratando de hacer lo mismo desde Android (usando la plataforma 7) estoy corriendo en varios problemas:
-
La impresora no parece que admita / necesita la autenticación de PIN. Al conectarme de OSX, acabo de seleccionar la opción que dijo "no utilice un perno" y lo emparejaron. En Android, cuando uso
device.createRfcommSocketToServiceRecord()
, siempre termina pidiéndome un PIN / clave (que no tengo / necesito). He resuelto esto usando el truco de reflexión:- Android Bluetooth Serial / RFCOMM / SPP, ¿Cómo cambiar el BAUD RATE?
- Delphi XE5 Serial Port en Android
- Bluetooth SPP entre Android y otras preguntas de dispositivos, UUID y PIN
- Comunicación en serie con Windows Phone 8
- Android RS232 a través de la toma de auriculares?
Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class}); BluetoothSocket connection = (BluetoothSocket) m.invoke(device, 1);
No estoy seguro si esto realmente funcionó, pero el LED parpadeante de la impresora deja de parpadear, lo que me hace creer que sí.
-
Una vez que tengo el zócalo, intento escribir datos del byte a la corriente usando:
byte[] buffer = new byte[3]; buffer[0] = (byte) 0x8A; buffer[1] = (byte) 0xC1; buffer[2] = (byte) 0x04; outStream.write(buffer); int response = inStream.read(); mySocket.close();
El envío de la misma secuencia de tres bytes de Coolterm en OSX imprimió una página de prueba de la impresora. Sin embargo, esto parece hacer que el hilo se bloquee en Android (la lectura).
¿Hay algo que estoy perdiendo aquí?
EDIT: Esto parece funcionar sólo cuando pongo el canal a 1. Así que significa que estoy en algo aquí.
- Detectar puertos serie instalados en dispositivos Android
- Arduino Mega recibe los datos correctos a través de la Serie 0 pero no la Serie 1-3
- Arduino: uso Serial y Software Serial con módulo bluetooth
- Comunicación con dispositivo USB serie en Android
- ¿Anular la tecla de eliminación en Android?
- Android Bluetooth - No se puede conectar
- Cómo hacer que Android y Arduino se comuniquen sin un módulo inalámbrico
Creo que estaba en el camino correcto. Aquí es un ejemplo de google que he utilizado para conectar a un micro-controlador de sello básico.
Todos los derechos reservados * Copyright (C) 2009 El Proyecto Abierto de Android * * Licenciado bajo la Licencia Apache, Versión 2.0 (la "Licencia"); * No puede usar este archivo excepto en cumplimiento con la Licencia. * Usted puede obtener una copia de la Licencia en * * Http://www.apache.org/licenses/LICENSE-2.0 * * A menos que sea requerido por la ley aplicable o acordado por escrito, el software * Distribuido bajo la Licencia se distribuye en una "COMO ESTÁ" BASE, * SIN GARANTÍAS O CONDICIONES DE NINGÚN TIPO, expresas o implícitas. * Consulte la Licencia para el idioma específico que rige los permisos y * Limitaciones bajo la Licencia. * / Package com.your_package; Import java.io.IOException; Import java.io.InputStream; Import java.io.OutputStream; Import java.utilADID; Import android.bluetooth.BluetoothAdapter; Importación android.bluetooth.BluetoothDevice; Import android.bluetooth.BluetoothServerSocket; Import android.bluetooth.BluetoothSocket; Import android.content.Context; Import android.os.Bundle; Import android.os.Handler; Import android.os.Message; Import android.util.Log; Todos los derechos reservados * Esta clase hace todo el trabajo para configurar y administrar Bluetooth * Conexiones con otros dispositivos. Tiene un hilo que escucha * Conexiones entrantes, un hilo para conectar con un dispositivo y un * Hilo para realizar transmisiones de datos cuando está conectado. * / Clase pública BluetoothService { // Depuración Private static final String TAG = "BluetoothService_BoeBot"; Private static final boolean D = true; // Nombre del registro SDP al crear el socket del servidor Private static final String NAME_SECURE = "BluetoothSecure"; Private static final String NAME_INSECURE = "BluetoothInsecure"; // UUID único para esta aplicación Private static final UUID MY_UUID_SECURE = UUID.fromString ("00001101-0000-1000-8000-00805F9B34FB"); Private static final UUID MY_UUID_INSECURE = UUID.fromString ("00001101-0000-1000-8000-00805F9B34FB"); // Campos miembros Privado final BluetoothAdapter mAdapter; Manejador final privado mHandler; Private AcceptThread mSecureAcceptThread; Private AcceptThread mInsecureAcceptThread; Privado ConnectThread mConnectThread; Private ConnectedThread mConnectedThread; Int mState privado; // Constantes que indican el estado de conexión actual Public static final int STATE_NONE = 0; // no estamos haciendo nada Public static final int STATE_LISTEN = 1; // ahora escuchando las conexiones entrantes Public static final int STATE_CONNECTING = 2; // ahora inicia una conexión saliente Public static final int STATE_CONNECTED = 3; // ahora conectado a un dispositivo remoto Todos los derechos reservados Constructor. Prepara una nueva sesión BluetoothChat. * @param context Contexto de la actividad de la UI * @param handler Un controlador para enviar mensajes a la actividad de la interfaz de usuario * / Public BluetoothService (Contexto del contexto, Handler handler) { MAdapter = BluetoothAdapter.getDefaultAdapter (); MState = STATE_NONE; MHandler = controlador; } Todos los derechos reservados * Establecer el estado actual de la conexión de chat * @param state Un entero que define el estado actual de la conexión * / Private sincronizado void setState (estado int) { Si (D) Log.d (TAG, "setState ()" + mState + "->" + estado); MState = estado; // Dar el nuevo estado al Handler para que la Actividad de la UI pueda actualizarse MHandler.obtainMessage (BoeBot.MESSAGE_STATE_CHANGE, state, -1) .sendToTarget (); } Todos los derechos reservados * Devuelve el estado de conexión actual. * / Public synchronized int getState () { Return mState; } Todos los derechos reservados * Iniciar el servicio de chat. Comienza específicamente AcceptThread para comenzar un * Sesión en el modo de escucha (servidor). Llamado por la actividad onResume () * / Public synchronized void start () { Si (D) Log.d (TAG, "inicio"); // Cancelar cualquier hilo que intente realizar una conexión If (mConnectThread! = Null) { MConnectThread.cancel (); MConnectThread = null; } // Cancelar cualquier subproceso que esté ejecutando una conexión If (mConnectedThread! = Null) { MConnectedThread.cancel (); MConnectedThread = null; } SetState (STATE_LISTEN); // Iniciar el hilo para escuchar en un BluetoothServerSocket If (mSecureAcceptThread == null) { MSecureAcceptThread = nuevo AcceptThread (true); MSecureAcceptThread.start (); } If (mInsecureAcceptThread == null) { MInsecureAcceptThread = new AcceptThread (false); MInsecureAcceptThread.start (); } } Todos los derechos reservados * Inicie ConnectThread para iniciar una conexión a un dispositivo remoto. * @param device El BluetoothDevice para conectar * @param secure Socket Tipo de seguridad - Seguro (verdadero), Inseguro (falso) * / Público sincronizado void connect (dispositivo BluetoothDevice, booleano seguro) { Si (D) Log.d (TAG, "conectarse a:" + dispositivo); // Cancelar cualquier hilo que intente realizar una conexión If (mState == STATE_CONNECTING) { If (mConnectThread! = Null) { MConnectThread.cancel (); MConnectThread = null; } } // Cancelar cualquier subproceso que esté ejecutando una conexión If (mConnectedThread! = Null) { MConnectedThread.cancel (); MConnectedThread = null; } tratar { // Iniciar el hilo para conectarse con el dispositivo dado MConnectThread = nuevo ConnectThread (dispositivo, seguro); MConnectThread.start (); SetState (STATE_CONNECTING); } Catch (excepción e) { } } Todos los derechos reservados * Inicie el ConnectedThread para comenzar a administrar una conexión Bluetooth * @param socket El BluetoothSocket en el que se realizó la conexión * @param device El BluetoothDevice que ha sido conectado * / Público sincronizado void conectado (socket BluetoothSocket, dispositivo BluetoothDevice, final String socketType) { Si (D) Log.d (TAG, "conectado, Tipo de socket:" + socketType); // Cancelar el subproceso que completó la conexión If (mConnectThread! = Null) { MConnectThread.cancel (); MConnectThread = null; } // Cancelar cualquier subproceso que esté ejecutando una conexión If (mConnectedThread! = Null) { MConnectedThread.cancel (); MConnectedThread = null; } // Cancelar el hilo de aceptar porque solo queremos conectarnos a un dispositivo If (mSecureAcceptThread! = Null) { MSecureAcceptThread.cancel (); MSecureAcceptThread = null; } If (mInsecureAcceptThread! = Null) { MInsecureAcceptThread.cancel (); MInsecureAcceptThread = null; } // Iniciar el subproceso para administrar la conexión y realizar transmisiones MConnectedThread = nuevo ConnectedThread (socket, socketType); MConnectedThread.start (); // Devuelve el nombre del dispositivo conectado a la actividad de la interfaz de usuario Mensaje msg = mHandler.obtainMessage (BoeBot.MESSAGE_DEVICE_NAME); Bundle bundle = nuevo Bundle (); Bundle.putString (BoeBot.DEVICE_NAME, device.getName ()); Msg.setData (paquete); MHandler.sendMessage (msg); SetState (STATE_CONNECTED); } Todos los derechos reservados Detener todos los hilos * / Public synchronized void stop () { Si (D) Log.d (TAG, "stop"); If (mConnectThread! = Null) { MConnectThread.cancel (); MConnectThread = null; } If (mConnectedThread! = Null) { MConnectedThread.cancel (); MConnectedThread = null; } If (mSecureAcceptThread! = Null) { MSecureAcceptThread.cancel (); MSecureAcceptThread = null; } If (mInsecureAcceptThread! = Null) { MInsecureAcceptThread.cancel (); MInsecureAcceptThread = null; } SetState (STATE_NONE); } Todos los derechos reservados * Escribir a la ConnectedThread de una manera no sincronizada * @param out Los bytes para escribir * @see ConnectedThread # write (byte []) * / Public void write (byte [] hacia fuera) { // Crear objeto temporal ConnectedThread r; // Sincronizar una copia de ConnectedThread Sincronizado (este) { If (mState! = STATE_CONNECTED) regreso; R = mConnectedThread; } // Realiza la escritura sin sincronizar R.write (out); } Todos los derechos reservados * Indica que el intento de conexión ha fallado y notifica la actividad de la UI. * / Private void connectionFailed () { // Enviar un mensaje de error a la actividad Mensaje msg = mHandler.obtainMessage (BoeBot.MESSAGE_TOAST); Bundle bundle = nuevo Bundle (); Bundle.putString (BoeBot.TOAST, "No se puede conectar el dispositivo"); Msg.setData (paquete); MHandler.sendMessage (msg); // Iniciar el servicio para reiniciar el modo de escucha BluetoothService.this.start (); } Todos los derechos reservados * Indica que se ha perdido la conexión y notifica la actividad de la UI. * / Private void connectionLost () { // Enviar un mensaje de error a la actividad Mensaje msg = mHandler.obtainMessage (BoeBot.MESSAGE_TOAST); Bundle bundle = nuevo Bundle (); Bundle.putString (BoeBot.TOAST, "Se ha perdido la conexión del dispositivo"); Msg.setData (paquete); MHandler.sendMessage (msg); // Iniciar el servicio para reiniciar el modo de escucha BluetoothService.this.start (); } Todos los derechos reservados * Este hilo se ejecuta mientras escucha las conexiones entrantes. Se comporta * Como un cliente del lado del servidor. Funciona hasta que se acepta una conexión * (O hasta cancelación). * / Clase privada AcceptThread extends Thread { // El socket del servidor local Privado final BluetoothServerSocket mmServerSocket; Private String mSocketType; Public AcceptThread (boolean secure) { BluetoothServerSocket tmp = nulo; MSocketType = seguro? "Seguro": "Inseguro"; // Crear un nuevo socket de servidor de escucha tratar { Si (seguro) { Tmp = mAdapter.listenUsingRfcommWithServiceRecord (NAME_SECURE, MY_UUID_SECURE); } Else { Tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord ( NAME_INSECURE, MY_UUID_INSECURE); } } Catch (IOException e) { Log.e (TAG, "Tipo de socket:" + mSocketType + "listen () falló", e); } MmServerSocket = tmp; } @Anular Public void run () { Si (D) { Log.d (TAG, "Tipo de socket:" + mSocketType + "BEGIN mAcceptThread" + este); } SetName ("AcceptThread" + mSocketType); Socket BluetoothSocket = nulo; // Escucha el socket del servidor si no estamos conectados Mientras que (mState! = STATE_CONNECTED) { tratar { // Esta es una llamada de bloqueo y sólo se devuelve en un // conexión exitosa o una excepción Socket = mmServerSocket.accept (); } Catch (IOException e) { Log.e (TAG, "Tipo de socket:" + mSocketType + "accept () falló", e); descanso; } // Si se aceptó una conexión If (socket! = Null) { Sincronizado (BluetoothService.this) { Conmutador (mState) { Caso STATE_LISTEN: Caso STATE_CONNECTING: // Situación normal. Inicie el hilo conectado. Conectado (socket, socket.getRemoteDevice (), mSocketType); descanso; Caso STATE_NONE: Caso STATE_CONNECTED: // Ya no está listo o ya está conectado. Termine el nuevo zócalo. tratar { Socket.close (); } Catch (IOException e) { Log.e (TAG, "No se pudo cerrar socket no deseado", e); } descanso; } } } } Si (D) { Log.i (TAG, "END mAcceptThread, socket Tipo:" + mSocketType); } } Public void cancelar () { Si (D) { Log.d (TAG, "Tipo de Socket" + mSocketType + "cancelar" + este); } tratar { MmServerSocket.close (); } Catch (IOException e) { Log.e (TAG, "Tipo de Socket" + mSocketType + "close () del servidor fallado", e); } } } Todos los derechos reservados * Este hilo se ejecuta al intentar realizar una conexión de salida * Con un dispositivo. Corre derecho; La conexión ya sea * Tiene éxito o falla. * / Clase privada ConnectThread extends Thread { Privado final BluetoothSocket mmSocket; Privado final BluetoothDevice mmDevice; Private String mSocketType; Public ConnectThread (dispositivo BluetoothDevice, seguro booleano) { MmDevice = dispositivo; BluetoothSocket tmp = nulo; MSocketType = seguro? "Seguro": "Inseguro"; // Obtener un BluetoothSocket para una conexión con el // dado BluetoothDevice tratar { Si (seguro) { Tmp = device.createRfcommSocketToServiceRecord (MY_UUID_SECURE); } Else { Tmp = device.createInsecureRfcommSocketToServiceRecord (MY_UUID_INSECURE); } } Catch (IOException e) { Log.e (TAG, "Tipo de socket:" + mSocketType + "create () falló", e); } MmSocket = tmp; } @Anular Public void run () { Log.i (TAG, "BEGIN mConnectThread SocketType:" + mSocketType); SetName ("ConnectThread" + mSocketType); // Siempre cancelar el descubrimiento porque ralentizará una conexión MAdapter.cancelDiscovery (); // Hacer una conexión con el BluetoothSocket tratar { // Esta es una llamada de bloqueo y sólo se devuelve en un // conexión exitosa o una excepción MmSocket.connect (); } Catch (IOException e) { // Cierra el socket tratar { MmSocket.close (); } Catch (IOException e2) { Log.e (TAG, "no se puede cerrar ()" + mSocketType + "socket durante un fallo de conexión", e2); } la conexión falló(); regreso; } // Restablece el ConnectThread porque hemos terminado Sincronizado (BluetoothService.this) { MConnectThread = null; } tratar { // Iniciar el subproceso conectado Conectado (mmSocket, mmDevice, mSocketType); } Catch (excepción e) { Log.e (TAG, "", e); } } Public void cancelar () { tratar { MmSocket.close (); } Catch (IOException e) { Log.e (TAG, "cerrar () de conectar" + mSocketType + "socket failed", e); } } } Todos los derechos reservados * Este hilo se ejecuta durante una conexión con un dispositivo remoto. * Maneja todas las transmisiones entrantes y salientes. * / La clase privada ConnectedThread extiende el hilo { Privado final BluetoothSocket mmSocket; Privado final InputStream mmInStream; Privado final OutputStream mmOutStream; Public ConnectedThread (socket BluetoothSocket, String socketType) { Log.d (TAG, "create ConnectedThread:" + socketType); MmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Obtenga los flujos de entrada y salida de BluetoothSocket tratar { TmpIn = socket.getInputStream (); TmpOut = socket.getOutputStream (); } Catch (IOException e) { Log.e (TAG, "enchufes temporales no creados", e); } MmInStream = tmpIn; MmOutStream = tmpOut; } @Anular Public void run () { Log.i (TAG, "BEGIN mConnectedThread"); Byte [] buffer = new byte [1024]; Bytes int; // Sigue escuchando el InputStream mientras está conectado Mientras que (verdadero) { tratar { // Lectura del InputStream Bytes = mmInStream.read (buffer); // Envía los bytes obtenidos a la actividad de la UI MHandler.obtainMessage (BoeBot.MESSAGE_READ, bytes, -1, buffer) .sendToTarget (); } Catch (IOException e) { Log.e (TAG, "desconectado", e); conexión perdida(); descanso; } } } Todos los derechos reservados * Escribir en el OutStream conectado. * @param buffer Los bytes para escribir * / Public void write (byte [] buffer) { tratar { MmOutStream.write (buffer); // Compartir el mensaje enviado de nuevo a la actividad de la interfaz de usuario MHandler.obtainMessage (BoeBot.MESSAGE_WRITE, -1, -1, buffer) .sendToTarget (); } Catch (IOException e) { Log.e (TAG, "Excepción durante la escritura", e); } } Public void cancelar () { tratar { MmSocket.close (); } Catch (IOException e) { Log.e (TAG, "close () del socket de conexión falló", e); } } } }
Prueba para ver si funciona.
BluetoothService mService = new BluetoothService(this, mHandler); mService.write(Bytes);
Google Cloud Print