2017-06-02 5 views
1

J'essaie de m'interfacer avec un périphérique USB OTG sur Android. Étant donné que le code est un peu long, je me contenterai de tracer les bases:Le périphérique USB OTG ne fonctionne pas après le débranchement et le rebranchement

  • Il y a une activité avec un filtre pour intention USB_DEVICE_ATTACHED (filtrée pour les ID de l'appareil que je suis intéressé par) déclarais dans le manifeste. Lorsque l'activité est lancée avec cette intention particulière, elle démarre un service et transmet le périphérique USB en tant qu'argument.
  • Lorsque le service démarre, il enregistre un récepteur de diffusion pour USB_DEVICE_DETACHED, puis se connecte au périphérique et commence à interagir avec lui (qui génère actuellement une sortie de journal).
  • Lorsque la diffusion de déconnexion USB est reçue et le périphérique est celui actuellement utilisé, close() est appelée sur la connexion de périphérique USB et le service s'arrête.

L'appareil est un tuner FM USB Si4701, qui se présente comme un périphérique USB HID.

Lors de la première connexion de l'appareil, je vois que mon service s'y connecte, peut changer de chaîne et recevoir des données RDS. Cependant, quand je le débranche et le rebranche, je vois le service se connecter à nouveau (et lire de nouveau avec succès les registres de périphériques), mais il ne change pas de fréquence et je ne vois jamais de données RDS.

Si je force l'application pour arrêter entre déconnectant et reconnectant l'appareil, l'appareil fonctionne normalement après VIEILLISSEMENT rebranché.

Cela suggère un nettoyage n'a pas lieu, ou d'une ressource n'est pas libéré correctement . Cependant:

  • Je ne conserve aucune structure de données liée au périphérique entre les connexions. Tout ce qui est lié à la connexion USB se trouve dans les instances de classe qui sont créées lorsqu'un périphérique est détecté et tous les membres statiques de ces classes sont définitifs.
  • Certaines choses fonctionnent après avoir rebranché le périphérique, telles que la lecture de registres pour les types de périphériques et la version du microprogramme (qui fonctionne en obtenant un rapport de fonctionnalité USB HID). L'initialisation définit également quelques registres (en envoyant un rapport de caractéristiques USB), ce qui ne renvoie pas d'erreur, mais la modification de la fréquence (qui implique également le réglage des registres) ne fonctionne pas.
  • Un intervalle de ~ 15 minutes entre le débranchement et le rebranchement n'a aucun effet (le périphérique ne fonctionne pas). D'un autre côté, si je débranche l'appareil, que je tue le service et que je le rebranche, cela fonctionne instantanément - le problème est donc clairement du côté Android, pas du côté de l'appareil.

Que dois-je faire pour que le périphérique USB fonctionne après un cycle de débranchement/rebranchement?

Répondre

0

Je ne comprends toujours pas complètement ce qui se passe ici, mais cela semble fonctionner maintenant.

Je dois mentionner que l'application est multi-thread et que la classe wrapper Si470x est appelée à partir de plusieurs threads. Comme cela a donné lieu à des conditions de concurrence (un thread accédant au périphérique quand un autre thread venait de le fermer), j'ai correctement déclaré toutes les méthodes comme synchronized afin que deux threads puissent accéder aux méthodes de la classe tuner en même temps.Branché l'appareil, débranché, branché - et voilà, il change de fréquence et crache les données RDS comme il est censé le faire.

Suspicion:

UsbDeviceConnection#close() pourrait ne pas être thread-safe.

Conclusions:

  • Appelez toujours UsbDeviceConnection#close() lorsque vous avez terminé avec l'appareil (y compris lorsque le dispositif est détaché).
  • Si votre application est multithread, assurez-vous que tout ce qui accède à votre connexion USB (directement ou indirectement) est correctement synchronisé.