Surveillance des connexions USB sur Android via diffusion système et interrogation périodique

Principe de détection des événements USB

Dans la plupart des cas, le système Android émet des diffusions (broadcasts) lors du branchement ou débranchement d'un périphérique USB, permettant ainsi une écoute simple. Cependant, certains appareils présentent des incompatibilités avec le système, empêchant l'émission de ces diffusions. Des approches alternatives deviennent alors nécessaires pour une détection fiable.

Écoute par diffusion système

Configuration du récepteur

Pour les périphériques USB standard, un BroadcastReceiver configuré avec les actions appropriées suffit.

public void configurerEcouteUSB() {
    IntentFilter filtre = new IntentFilter();
    filtre.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    filtre.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    detecteurUSB = new DetecteurUSB();
    enregistrementContexte.registerReceiver(detecteurUSB, filtre);
}

Traitement des événements reçus

private class DetecteurUSB extends BroadcastReceiver {
    @Override
    public void onReceive(Context contexte, Intent intention) {
        UsbDevice peripherique = intention.getParcelableExtra(UsbManager.EXTRA_DEVICE);
        String action = intention.getAction();
        
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            // Traitement pour connexion
        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            // Traitement pour déconnexion
        }
    }
}

Gestion des périphériques d'entrée

Les dispositifs d'entrée (calviers, scanners, souris) nécessitent un mécanisme spécifique via InputManager.

public class EcouteurPeripheriqueEntree implements InputManager.InputDeviceListener {
    @Override
    public void onInputDeviceAdded(int identifiant) {
        // Nouveau périphérique d'entrée détecté
    }

    @Override
    public void onInputDeviceRemoved(int identifiant) {
        // Périphérique d'entrée retiré
    }

    @Override
    public void onInputDeviceChanged(int identifiant) {
        // Changement de propriétés détecté
    }
}

// Initialisation
InputManager gestionnaireSaisie = (InputManager) getSystemService(Context.INPUT_SERVICE);
gestionnaireSaisie.registerInputDeviceListener(new EcouteurPeripheriqueEntree(), null);

Nettoyage des ressources

public void libererEcouteurs() {
    enregistrementContexte.unregisterReceiver(detecteurUSB);
    gestionnaireSaisie.unregisterInputDeviceListener(ecouteurPeripherique);
}

Détection par interrogation périodique

En cas d'incompatibilité système où les diffusions ne fonctionennt pas, une méthode alternative consiste à interroger régulièrement la liste des périphériques USB.

Récupération des périphériques connectés

UsbManager gestionnaireUSB = (UsbManager) contexte.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> inventairePeripheriques = gestionnaireUSB.getDeviceList();

Filtrage pour un type spécifique

Exemple de détection d'une caméra USB par ses descripteurs de classe :

public UsbDevice rechercherCameraUSB() {
    if (inventairePeripheriques != null) {
        for (UsbDevice appareil : inventairePeripheriques.values()) {
            if (verifierClasseCamera(appareil)) {
                return appareil;
            }
        }
    }
    return null;
}

private boolean verifierClasseCamera(UsbDevice appareil) {
    return appareil != null 
        && appareil.getDeviceClass() == 239 
        && appareil.getDeviceSubclass() == 2;
}

Implémentation de l'interrogation

Observable.interval(0, 5, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(periode -> {
        boolean cameraPresente = rechercherCameraUSB() != null;
        // Mise à jour de l'état de l'interface utilisateur
        mettreAJourInterface(cameraPresente);
    });

Cette technique offre une solution de secours pour les environnements systèmes problématiques, bien que l'écoute par diffusion reste la méthode recommandée pour les appareils compatibles.

Étiquettes: Android UsbManager BroadcastReceiver InputManager rxjava

Publié le 16 juin à 23h14