[Android 3.1] USB Host Attach

miffi

Erfahrenes Mitglied
Howdie zusammen.

Nach längerer Abwesenheit mal wieder hier im Java-Forum :)
Und direkt mit einem Problem:

Nachdem ich ein Iconia Tab auf Android 3.1 mit USB-Host-Unterstützung gepatched habe, habe ich mich gleich mal ans Ausprobieren gemacht. Wers noch nicht kennt - eine (IMHO zu kurz gehaltene) Einführung gibts >>hier<<.

Die Intent-Filter im Manifest habe ich erfolgreich hinzugefügt. D.h., wenn ich ein USB-Device mit passender Vendor- und Produkt-ID anschließe, wird meine App bzw. Activity aufgerufen. In der onCreate()-Methode meiner Hauptaktivity registriere ich auch einen BroadcastReceiver, der auf Attach-/Detach-Intents hören soll. Hierbei geht Detach ohne Probleme, aber Attach-Intents bekommt der Receiver anscheinend einfach nicht mit.

Testhalber habe ich den Intent-Filter im Manifest rausgeworfen, um den Broadcast-Receiver in einer bereits gestarteten App die Erkennung von USB-Devices zu überlassen - auch hier keine erkannten Attach-Intents.

Hat von euch bereits jemand Erfahrung mit USB-Host unter Android und kann mir helfen?
Der Code ist IMHO zu spezifisch (und nahezu identisch mit den Samples) um ihn hier zu posten. Sollte es gewünscht bzw. nötig sein, werd ich das natürlich gern nachholen.

Grüße
miffi

P.S.: Nur mal so als Diskussions-Anstoß - die USB-Host-Geschichte scheint noch nicht so richtig ausgereift zu sein, oder? Z.B. muss man sich entscheiden, eine Activity entweder vom Attach-Intent oder per Launcher auszuführen. Beides gleichzeitig ist ja unschön, da das Activity sonst ein zweites Mal offen ist (mit singleInstance-Option muckt der Intent-Filter) und daher auch 2x die Back-Taste fürs Schließen betätigt werden muss...
 

miffi

Erfahrenes Mitglied
So, nachdem ich mich eine ganze Weile mit USB-Host unter Android beschäftigt habe, hier mein Fazit. Falls mal jemand auf diesen Thread stößt und ähnliche Probleme hat, möchte ich meine gestellte Frage nicht unbeantwortet lassen.

Nachdem ich in vielen Foren recherchiert und diskutiert habe (auch im semi-offiziellen Android-Forum stackoverflow), kam ich zu dem Schluss, dass die USB-Host-Geschichte tatsächlich unausgereift ist. Meine Lösung war im Endeffekt, die Intent-Filter im Manifest wegzulassen und in der Applikation selbst die angeschlossenen USB-Geräte zu enumerieren. Dies hat den Nachteil, dass die Applikation (im Gegensatz zum Intent-Filter) keine automatische Permission hat, mit einem gefundenen USB-Gerät zu kommunizieren - diese muss durch einen Prompt vom User erteilt werden.

Je nach Anforderung kann ich die folgenden zwei Vorgehensweisen empfehlen. Als Anmerkung sei hier festgehalten, dass ich noch nicht lange für Android entwickle und manche vermeintliche Fehler vielleicht einfach nur mangelndes Wissen (z.B. über savedInstanceState-Bundles) sind.
  1. Applikation starten mit USB-Attach und reagieren/beenden bei USB-Detach
    Hier empfiehlt sich ein Intent-Filter im Manifest, der die Applikation automatisch aufruft, sobald das entsprechende Gerät angeschlossen wird. In der Applikation sollte ein Broadcast-Receiver aufgesetzt werden, der die Applikation benachrichtigt (bzw. beendet), sobald er das USB-Detach-Event empfängt. Der Receiver hört nicht auf Attach-Events, obwohl er das sollte.
    Ich habe anfangs angenommen, dass der Intent-Filter das Event bereits konsumiert, der Receiver das Event also gar nicht mitbekommen kann. Aber auch ohne Intent-Filter kommt nichts beim Receiver an.

    Dieses Vorgehen empfiehlt sich meiner Erfahrung nach NICHT, wenn man in einer laufenden Applikation dynamisch USB-Geräte an/abstecken möchte oder mehrere Devices enumerieren will. Wie im Frage-Post angedeutet, startet der Intent-Filter die Activity ein zweites Mal bei einem zweiten angeschlossenen Gerät (oder auch, wenn das erste Gerät abgesteckt wurde, ohne dass die Activity, die durch den Intent-Filter geöffnet wurde, beendet wurde), was unschön ist und unvorhersehbare Konsequenzen haben kann. Es kann aber auch sein, dass man dies mit einer Kombination aus SingleInstance-Option und dem Bundle-Parameter lösen kann - das konnte ich noch nicht testen. Bei mir lief die USB-Initialisierung in der onCreate()-Methode ab, vielleicht kann man das besser lösen.
  2. Applikation auch ohne USB-Gerät/mit mehreren USB-Geräten
    Das ist die Option, die ich für mein Projekt gewählt habe, da meine Applikation auch ohne angeschlossene Geräte lauen soll. Der Intent-Filter der Haupt-Activity ist also ganz normal auf LAUNCHER und MAIN eingestellt. Man kann über den USB-Manager (Vorgehen siehe im ersten Post verlinktes Tutorial von android-developers) die angeschlossenen Geräte enumerieren. Dies kann man beispielsweise über einen Scan-Button oder (wie in meinem Fall) eine State-Machine angehen. Die Kommunikation selbst kann dann aber wie beschrieben erst nach einer vom User erteilten Permission intialisiert werden.

Ich hege die Hoffnung, dass mit vor der Tür stehenden Android 4 noch ein wenig am USB-Host nachgearbeitet wird.

Grüße
miffi
 
Zuletzt bearbeitet:

Neue Beiträge