Saltar al contenido

Ionic Bluetooth

Bluetooth Ionic

¿Buscando comunicarte con otro dispositivo desde tu app hecha en Ionic con Ionic Ionic Bluetooth? O, tal vez, ya sabes cómo hacerlo perto te falta algún detalle más para implementarlo cómo tu quieres ¿verdad?

Si has respondido que si a cualquiera de estas preguntas, tranquilo. No eres el único, ni serás el último, que se las ha hecho.

Es más, hasta los devs más expertos nos las hacemos amenudo cuando tenemos que hacer una integración nueva de algo que no conocemos o que llevamos mucho sin usar.

Mi nombre es Aitor Sánchez y soy desarrollador de aplicaciones desde el año 2014, y en este artículo te enseñaré cómo implementar Ionic Bluetooth en tu aplicación para que puedas comunicarte correctamente con otros dispositivos.

Pero antes de continuar, este es El Círculo. Es mi newsletter donde te puedo enseñar desarrollo de apps móviles, aso y monetización. Por cierto, si te suscribes te regalo mi ebook Duplica los ingreso de tus apps en 5 minutos. No es broma.

P.D: Darse de alta es gratis y de baja, también.

 

Instalación de Ionic Bluetooth

Como todos los componentes externos, que no vienen en el core de manera predeterminada, tenemos que proceder con su instalación. Para ello vamos a utilizar los dos siguientes comandos de consola:

 

$ ionic cordova plugin add cordova-plugin-bluetooth-serial
$ npm install --save @awesome-cordova-plugins/bluetooth-serial

 

Vale, la primera línea hace referencia a la instalación del plugin de Cordova que hará de puente entre el código TS y el código nativo de la plataforma.

La segunda instala el código TS necesario para poder hacer uso de este componente. Este código es el que se pondrá en contacto con el plugin que hemos visto en el párrafo anterior para ejecutar las funciones nativas.

Una vez realizados estos dos pasos tenemos que importar en nustros providers la clase, para que así sea posible su inyección en los constructores.

...
import { BluetoothSerial } from '@awesome-cordova-plugins/bluetooth-serial/ngx';
...

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    ...
  ],
  providers: [
    ...
    BluetoothSerial, //Esta es la línea importante.
    ...
  ]
})

¿Ves? Lo metemos dentro del array de imports para que podamos usarlo.

Bien, pues hasta aquí llega la instalación, continuemos.

 

Configuración de Ionic Bluetooth

Bueno, pues un paso que nos vamos a saltar. Hasta la versión actual del componente no es necesaria una actualización previa. Así que pasemos al siguiente paso.

 

Como se usa Bluetooth serial Ionic

Bueno, ya comenzamos a entrar en materia. Ahora vamos a ver cómo podemos usar todo este tinglado que hemos montado. La verdad es que no es complejo como muchos creen. Pero vamos a ponernos manos a la obra para que juzgues por ti mismo.

En primer lugar, vamos a ver un pedazo de código en el que apoyarnos.

 

import { BluetoothSerial } from '@awesome-cordova-plugins/bluetooth-serial/ngx';

constructor(private bluetoothSerial: BluetoothSerial) { }


// Write a string
this.bluetoothSerial.write('hello world').then(success, failure);

// Array of int or bytes
this.bluetoothSerial.write([186, 220, 222]).then(success, failure);

// Typed Array
var data = new Uint8Array(4);
data[0] = 0x41;
data[1] = 0x42;
data[2] = 0x43;
data[3] = 0x44;
this.bluetoothSerial.write(data).then(success, failure);

// Array Buffer
this.bluetoothSerial.write(data.buffer).then(success, failure);

 

Este ejemplo solo hará uso de un envío de datos. Después veremos lo necesario para escanear dispositivos o recibir datos. Pero hasta ahora, mantengamos esto aquí.

  1. La primera línea hace referencia a la importación del módulo dentro de nuestro componente.
  2. Después, en la segunda, inyectamos una isntancia de BluetoothSerial en nuestro constructor. Así podremos usar el código de una manera más limpia y ordenada.
  3. Seguimos con la siguiente línea: La función “write” nos permite escribir sobre el buffer abierto los datos que veamos oportunos. Podrán ser solo dos. Por un lado, una cadena de texto o String o un array de bytes.
  4. Vale, ¿hasta aquí todo correcto? Me alegro. Para terminar el ejemplo decir que la función “write” devuelve una promesa que tendremos que controlar con un “then”.

Los parámetros que recibe son, el primero el Succes que hace referencia a los datos correctos y el segundo, failure, en caso de que haya habido cualquier problema.

 

Funciones y campos de la clase Bluetooth en Ionic

Con lo anterior, ya deberías haber entendido todo el proceso y la lógica del componente. Ahora vamos a ver los campos de clase y los métodos que tenemos disponibles para tratar con él.

Nota: Como digo en todos los tutos. Solo hablaremos de los campos de este componente. Los heredados serán tratados a parte en otros tutoriales.

 

connect(macAddres_or_uuid)

Esta función intentará realizar una conexión sobre otro dispositivo.

  • macAddres_or_uuid – > String – > El identificador del dispositivo al que nos queremos conectar. Sea la dirección mac del dipositivo o el identificador único del hadware.
  • Retorno -> Observable -> Al hacer el suscribe nos conectaremos con el destino y al hacer el unSuscribe nos desconectaremos. En los parámetros nos llega la referencia de conexión para tratar con ella.

 

connectInsecure(macAddress)

Aunque no lo hemos comentado, la función anterior se conecta de manera segura a un dispositivo. Así que esta es la misma, pero con una conexión insegura.

La única diferencia es que el envío de datos no se encriptará en está. Dejando al descubierto todos los dados que son enviados o recibidos.

  • macAddress – > String – > El identificador del dispositivo al que nos queremos conectar. Sea la dirección mac del dipositivo o el identificador único del hadware.
  • Retorno -> Observable -> Al hacer el suscribe nos conectaremos con el destino y al hacer el unSuscribe nos desconectaremos. En los parámetros nos llega la referencia de conexión para tratar con ella.

 

disconnect()

Como el propio nombre indica, se desconecta de la conexión actual.

  • Retorno -> promesa -> Dentro del “then” de la promise vendrán los datos de desconexión.

 

write(data)

Como hemos visto en el ejemplo, nos permite escribir sobre el buffer de datos que hay abierto hasta el otro extremo.

  • Data -> String / Any -> Una cadena de texto o un array de bytes que son los que serán recibidos en el destino.
  • Retorno -> promesa -> La promise trae consigo los datos de si se ha escrito correctamente el mensaje o no.

 

Available()

Esta función nos permite conocer el estado de la conexión antes de escribir o esperar datos a través del buffer.

  • Retorno -> promesa -> Dependiendo del estado de la conexión la promesa retornará true o false.

 

read()

Como su propio nombre indica, nos permite leer el buffer de datos que nos llega desde el otro extremo.

  • Retorno -> promesa -> Nos devuelve los datos que vienen a través del buffer en el success de la promesa. El buffer no se cierra así que el código en el interior se ejecutará cada vez que se recibe algo.

 

readUntil(delimitador)

El similar al método anterior, pero le pone un límite a la entrada de datos. EL buffer solo se leerá hasta donde nosotros le digamos en lugar de entero. En caso de que la longitud devuelta sea menor, el resto devolverán valores vacíos.

  • Delimitador -> String -> El delimitador se asigna aquí. Digamos que cuando el buffer coincida con la cadena que hemos pasado parará.
  • Retorno -> promesa -> Nos devuelve los datos que vienen a través del buffer en el success de la promesa. El buffer no se cierra así que el código en el interior se ejecutará cada vez que se recibe algo.

 

suscribeRawData()

Esta función devuelve un observable que es notificado cada vez que hay nuevos datos en el buffer.

  • Retorno -> Observable -> Se ejecutará cuando haya nuevos datos en el buffer de entrada.

 

clear()

Limpia el buffer de datos para que no haya interferencia con la recepción o el envío.

  • Retorno -> promesa -> Retorna una promesa cuando la limpieza haya sido completada.

 

list()

Esta función nos permite saber cuáles son los dispositivos que están enlazados a nuestro equipo en ese preciso momento.

  • Retorno -> promesa -> Con la promesa viene el array de direcciones que están vinculadas con nosotros.

 

isEnabled()

Esta función nos permite conocer si el componente de hardware para bluettoth en nuestro dispositivo está encendido o apagado.

  • Retorno -> promesa – > Con la promesa llegan los datos (true o false) para conocer si está encendido o no.

 

isConnected()

Comprueba si nuestro dispositivo se encuentra vinculado en este mismo momento.

  • Retorno -> promesa -> Con esta promesa llegan los datos en factor booleano que nos permiten conocer si está conectado o no.

 

showBluetoothSettings()

Este método abre la ventana de configuración de Bluettoth del dispositivo para que el usuario pueda encenderlo/apagarlo, etc…

  • Retorno – > Promesa -> Simplemente lanza el “then” en caso de que todo haya funcionado.

 

enable()

Hace una solicitud de activación del componente físico Bluetooth.

  • Retorno -> Promesa -> Simplemente entra por el “then” en caso de que haya sido activado y por el “catch” en caso contrario.

 

discoverUnpaired()

Esta función realiza un escaneo de la red al alcance y nos devolverá un array con los posibles dispositivos a los que se puede vincular.

  • Retorno -> Promesa -> En los parámetros recibidos en esta promesa se incluye la lista de dispositivos a los que nos podemos asociar.

 

setDeviceDiscoveredListener()

Este método nos permite definir un oyente que ejecutará el código contenido cuando se encuentra un nuevo dispositivo dentro de la red del bluetooth.

  • Retorno -> Observable -> Al suscribirnos, el retorno que nos ofrecerá el similar al de la función “discoverUnpaired” lo que pasa que esta función se ejecutará automática en lugar de estar llamando a este método.

 

setName(nuevoNombre)

Fija un nuevo nombre a nuestro dispositivo. Este nombre será el que aparecerá en otros dispositivos cuando escanean la red.

  • nuevoNombre -> String -> El nuevo nombre que queremos asignar a nuestro dispositivo.

 

setDiscoverable(duracion)

Pone nuestro dispositivo en modo visible para otros.

  • Duración -> number -> La duración, en milisegundos, que queremos que nuestro dispositivo sea rastreable por otros dispositivos.

 

Bueno compañ[email protected] del metal. Aquí me despido ya. Este artículo ha sido bastante intenso y extenso. La verdad que terminado un poco cansado de redactarlo, para que nos vamos a engañar J. Pero bueno, con esto podrás darte una idea muy concreta y profunda de lo que podemos llegar a realizar con algo como esto.

Simplemente me queda despedirme de ti, y decirte que nos vemos en el siguiente artículo. Un saludo y nos vemos pronto.

 

Ionic Bluetooth example, un ejemplo funcional

Siempre me gusta dar lo mejor a mis usuarios, y cómo es costumbre, y si pasas por aquí lo verás a menudo, ponemos ejemplos en todo lo que hacemos. Así que este no va a ser menos.

Esta vez vamos a hacer un ejemplo funcional al 100%, así que si tienes alguna duda después, no dudes en preguntar en los comentarios que para eso estamos.

En el ejemplo, emparejaremos (también denominado pairing) nuestra app a otro dispositivo y, por otro lado, mostraremos los dispositivos que tenemos emparejados.

No vamos a incurrir en la configuración ni nada que hayamos visto a lo largo del artículo, así que directos al grano. Si no te funciona, comienza desde el principio del artículo.

Nota importante: El siguiente código es un código improvisado y está sujeto a fallos de Sintaxis.

 

import { BluetoothSerial } from '@awesome-cordova-plugins/bluetooth-serial/ngx';
import {AlertController, ToastController} from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
pairedList: pairedList;
listToggle: boolean = false;
pairedDeviceId: number = 0;
dataSend = "";
constructor(public navCtrl: NavController, private alertCtrl: AlertController, private bluetoothSerial: BlueetoothSerial, private toastCtrl: ToastController) {
this.checkBlueroothEnable();
}
checkBluetoothEnable() {
this.bluetoothSerial.isEnable().then(success => {
this.listPairedDevices();
}, error => {
this.showError("Por favor, activa el Bluetooth");
})
}
listPairedDevices() {
this.bluetoothSerial.list().then(success => {
this.pairedList = success;
this.listToggle = true;
}, error => {
this.showError("Ha sucedido un error al recuperar la lista, inténtalo de nuevo");
this.listToggle = false;
})
}
selectDevice() {
let connectedDevice = this.pairedList[this.pairedDeviceId];
if (!connectedDevice.address) {
this.showError("Selecciona un dispositivo al que conecterse");
return;
}
let address = connectedDevice.address;
let name = connectedDevice.name;
this.connect(address);
}
connect(address) {
this.bluetoothSerial.connect(address).subscribe(success => {
this.deviceConnected();
this.showToast("Conectado correctamente");
}, error => {
this.showError("No se ha podido conectar, algo ha fallado.");
})
}
deviceConnected() {
this.bluetoothSerial.subscribe("\n").subscribe(success => {
this.handleData(success);
this.showToast("Conectado correctamente")
}, error => {
this.showError(error);
})
}
deviceDisconnect() {
this.bluetoothSerial.disconnect();
this.showToast("Se ha desconectado del dispositivo");
}
handleData(data) {
//Montar aquí el sistema para tratar la entrada desde el dispositivo al que nos hemos conectado.
this.showToast(data);
}
sendData(dataToSend: String) {
this.dataSend = "\n";
this.dataSend += dataToSend;
this.bluetoothSerial.write(this.dataSend).then(success => {
this.showToast(success);
}, error => {
this.showError(error);
})
}
showError(message: String) {
let alert = this.alertCtrl.create({
title: "¡Error!",
subTitle: message,
buttons: ['dismiss']
});
alert.present();
}
showToast(message: String) {
let toast = this.toastCtrl.create({
message: message,
duration: 5000
});
toast.present();
}
}
interface pairedList {
'class': number,
'id': String,
'address': String,
'name': String
}

 

Bueno, pues ahí está. Repito, es un código improvisado y sujeto a fallos de sintaxis. Pero analizándolo es 100% funcional. Simplemente remplaza el «sendData» y el «handleData» por lo que creas oportuno y listo. Ahí tienes una interfaz Bluettoth funcionando.

Quizás muchos me diréis después de ver esto que estoy loco, por cómo está escrito el código, pero recordar que es didactico y pensado para que se entienda. La abstracción se la tiene que aplicar cada uno cómo lo crea oportuno.

 

Ionic Bluetooth Printer, cómo imprimir en una impresora Bluetooth

Hablando con un colega de batallas, este me comentó que por que no incluia en el artículo cómo podemos imprimir en una impresora mediante una aplicaicón Ionic a través de esta tecnología. Me pareció una genial idea así que me puse manos a la obra… Cuando iba por la mitad del tuto me di cuenta de que nos haría falta un artículo adicional completo para explicarlo buien y eso no está dentro de los planes de la web, al menos por ahora.

Pero si estás buscando esta información y has caido aquí, te dejo un enlace donde podrás saber cómo se hace. La única pega, está en inglés… Para mi no es problema, pero para tí quizás sí. Pero bueno, menos es nada, por lo menos hasta que haga el tuto y lo suba a la web.

Este es el enlace: https://github.com/katzer/cordova-plugin-printer

 

Más tutoriales de Ionic

 

Para terminar, y cómo es costumbre para los más ganduletes, aquí os dejo un tutorial en vídeo:

 

 

Y ya me despido. La verdad que me ha gustado escribir este artículo. Ha sido gratificante el escribir el ejemplo completo por que hacía tiempo que no tocaba algo del estilo y me he acordado de todo.

Pues sin mucho más que añadir me despido ya hasta el próximo artículo. Un saludo y que vaya todo genial.