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.