Architecture d'impression Bluetooth avec UniApp : Concevoir une solution mobile multiplateforme

L'interaction entre les applications mobiles et les périphériques matériels est devenue un pilier de la transformation numérique, notamment dans les secteurs de la logistique et de la vente au détail. L'utilisation du framework UniApp pour piloter des imprimantes thermiques via Bluetooth permet de déployer des solutions performantes tout en partageant une base de code unique. Cet article analyse les principes architecturaux nécessaires pour bâtir un moteur d'impression robuste et compatible avec le protocole CPCL.

Conception de l'architecture logicielle

Pour garantir la maintenabilité, une architecture en couches est privilégiée. Elle sépare la logique métier de la gestion de bas niveau du matériel. Dans un environnement UniApp, cela se traduit par l'utilisation de la compilation conditionnelle pour accéder aux API natives Android via l'objet plus.android.

// Exemple d'initialisation des classes natives sous Android
// #ifdef APP-PLUS
const BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
const BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
const UUID = plus.android.importClass("java.util.UUID");
// #endif

Protocole de communication et gestion SPP

La plupart des imprimantes portables utilisent le profil de port série (SPP). La communication repose sur l'établissement d'un canal RFCOMM via un identifiant unique (UUID) standardisé. Le processus commence par la récupération de l'adaptateur local pour ensuite cibler l'adresse MAC de l'imprimante.

async function etablirConnexion(adresseMac) {
    const identifiantService = "00001101-0000-1000-8000-00805F9B34FB";
    const adaptateurBT = BluetoothAdapter.getDefaultAdapter();
    const peripheriqueDistant = adaptateurBT.getRemoteDevice(adresseMac);
    
    try {
        let socketImpression = peripheriqueDistant.createInsecureRfcommSocketToServiceRecord(
            UUID.fromString(identifiantService)
        );
        socketImpression.connect();
        return socketImpression;
    } catch (erreur) {
        console.error("Échec de la liaison Bluetooth", erreur);
        throw erreur;
    }
}

Génération de commandes CPCL

Le langage CPCL ( Zebra ) est la norme de fait pour l'impression d'étiquettes. Plutôt que de manipuler des chaînes brutes, il est conseillé d'encapsuler la création des commandes dans des fonctions modulaires. Cela permet de gérer dynamiquement les dimensions, les textes et les codes QR.

function genererTicket(donnees) {
    let commande = "! 0 200 200 400 1\r\n"; // En-tête : décalage, résolution, hauteur
    commande += "PAGE-WIDTH 580\r\n";
    
    // Ajout du texte
    commande += `TEXT 4 0 20 10 ${donnees.titre}\r\n`;
    commande += `TEXT 7 0 20 60 Ref: ${donnees.reference}\r\n`;
    
    // Configuration du Code QR
    commande += "BARCODE QR 150 120 M 2 U 6\r\n";
    commande += `MA,${donnees.codeQr}\r\n`;
    commande += "ENDQR\r\n";
    
    commande += "PRINT\r\n";
    return commande;
}

Gestion des flux et encodage des données

Un défi majeur lors de l'impression mobile est le support des caractères spéciaux. La conversion des chaînes de caractères en tableaux d'octets doit souvent respecter l'encodage GBK ou CP1252 selon le matériel ciblé. L'envoi des données s'effectue via un flux de sortie (OutputStream).

function envoyerDonnees(socket, contenu) {
    try {
        const fluxSortie = socket.getOutputStream();
        // Conversion de la chaîne en octets avec l'encodage spécifique
        const octets = plus.android.invoke(contenu, "getBytes", "GBK");
        fluxSortie.write(octets);
        fluxSortie.flush();
    } catch (e) {
        uni.showToast({ title: "Erreur de transmission", icon: 'none' });
    }
}

Stabilité et gestion des erreurs

La robusetsse du système d'impression dépend de la gestion proactive du cycle de vie des ressources. Il est impératif de vérifier l'état du socket avant chaque opération et de fermer les connexions pour éviter les fuites de mémoire ou le blocage de l'adaptateur Bluetooth.

  • Surveillance de l'état : Utiliser des mécanismes de "heartbeat" ou vérifier la propriété isConnected() avant l'envoi.
  • Libération des ressources : Toujours appeler socket.close() dans un bloc finally ou lors de la destruction du composant.
  • File d'attente : Pour l'impression de masse, implémenter une file d'attente (Buffer) afin de ne pas saturer la bande passante Bluetooth.

Scénarios d'application industrielle

Cette architecture est partiuclièrement adaptée aux applications de terrain :

  1. Logistique : Impression de bordereaux de livraison et d'étiquettes de suivi de colis en temps réel.
  2. Gestion de stock : Création instantanée d'étiquettes d'inventaire avec codes-barres lors de la réception de marchandises.
  3. Commerce : Émission de tickets de caisse ou de reçus de paiement pour les vendeurs nomades.

Étiquettes: uniapp Bluetooth-SPP CPCL Android-Native Impression-Thermique

Publié le 22 juillet à 14h58