Java.io.IOException, "bad file number" USB-Verbindung
Ich bin einrichten eines USB-Zubehör die Verbindung zwischen meinem Android-Telefon und einem anderen Gerät. Nur das senden und bytes hin-und-her jetzt zu testen. Ich bekomme einige eindeutige Kommunikation geht auf den ersten, aber es endet immer sterben, mit Java.io.IOException: write failed: EBADF (Bad file number)"
nach einer Sekunde oder so. Manchmal ist das Lesen am Leben bleibt, aber die Schrift stirbt; die anderen beiden sterben.
Ich mache nichts super schickes, Lesen und schreiben genau wie die Google-Dokumentation:
Ersten Verbindung (innerhalb des broadcast-receiver, ich weiß, das Teil funktioniert zumindest anfänglich):
if (action.equals(ACTION_USB_PERMISSION))
{
ParcelFileDescriptor pfd = manager.openAccessory(accessory);
if (pfd != null) {
FileDescriptor fd = pfd.getFileDescriptor();
mIn = new FileInputStream(fd);
mOut = new FileOutputStream(fd);
}
}
Lesen:
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
byte[] buf = new byte[BUF_SIZE];
while (true)
{
try {
int recvd = mIn.read(buf);
if (recvd > 0) {
byte[] b = new byte[recvd];
System.arraycopy(buf, 0, b, 0, recvd);
//Parse message
}
}
catch (IOException e) {
Log.e("read error", "failed to read from stream");
e.printStackTrace();
}
}
}
});
thread.start();
Schreiben:
synchronized(mWriteLock) {
if (mOut !=null && byteArray.length>0) {
try {
//mOut.flush();
mOut.write(byteArray, 0, byteArray.length);
}
catch (IOException e) {
Log.e("error", "error writing");
e.printStackTrace();
return false;
}
}
else {
Log.e(TAG, "Can't send data, serial stream is null");
return false;
}
}
Error-stacktrace:
java.io.IOException: write failed: EBADF (Bad file number)
W/System.err(14028): at libcore.io.IoBridge.write(IoBridge.java:452)
W/System.err(14028): at java.io.FileOutputStream.write(FileOutputStream.java:187)
W/System.err(14028): at com.my.android.transport.MyUSBService$5.send(MyUSBService.java:468)
W/System.err(14028): at com.my.android.transport.MyUSBService$3.onReceive(MyUSBService.java:164)
W/System.err(14028): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:781)
W/System.err(14028): at android.os.Handler.handleCallback(Handler.java:608)
W/System.err(14028): at android.os.Handler.dispatchMessage(Handler.java:92)
W/System.err(14028): at android.os.Looper.loop(Looper.java:156)
W/System.err(14028): at android.app.ActivityThread.main(ActivityThread.java:5045)
W/System.err(14028): at java.lang.reflect.Method.invokeNative(Native Method)
W/System.err(14028): at java.lang.reflect.Method.invoke(Method.java:511)
W/System.err(14028): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
W/System.err(14028): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
W/System.err(14028): at dalvik.system.NativeStart.main(Native Method)
W/System.err(14028): Caused by: libcore.io.ErrnoException: write failed: EBADF (Bad file number)
W/System.err(14028): at libcore.io.Posix.writeBytes(Native Method)
W/System.err(14028): at libcore.io.Posix.write(Posix.java:178)
W/System.err(14028): at libcore.io.BlockGuardOs.write(BlockGuardOs.java:191)
W/System.err(14028): at libcore.io.IoBridge.write(IoBridge.java:447)
W/System.err(14028): ... 13 more
Habe ich die Protokollierung alle über dem Platz und ich somit weiß, dass es nicht etwas zu offensichtlich, wie eine andere Erlaubnis-Anfrage empfangen wird (und damit der Datei-streams wird neu initialisiert Mitte Lesen). Die streams nicht schließen, denn ich habe mir nie passieren, dass irgendwo in meinem code (für jetzt). Ich bin nicht immer alle freistehend oder befestigt Ereignisse entweder (ich log, dass, wenn es passiert). Es scheint nichts außergewöhnliches, es ist einfach stirbt.
Ich dachte, vielleicht war es ein concurrency-Problem, also spielte ich mit Schlösser und schläft, nichts funktionierte, dass ich es versucht habe. Ich glaube nicht, dass es ein Durchsatz Problem, entweder, weil es immer noch passiert, wenn ich schlafe jeder Lesen (an beiden enden), und Lesen Sie ein einziges packet at a time (super slow bitrate). Gibt es eine chance, dass der Puffer ist überrollt, und am anderen Ende irgendwie? Wie würde ich mich über die Aufklärung dieser? Ich habe Zugriff auf das andere Ende code, es ist ein Android-Gerät als auch mit Host-Modus. Im Falle, dass es darauf ankommt, kann ich post, dass der code zu - standard-bulk-transfers.
Funktioniert das Telefon nur haben glanzlose Unterstützung für Android-Accessory-Modus? Ich habe versucht, zwei Handys und beide scheitern gleichermaßen, so bezweifle ich, es ist, dass.
Frage ich mich, was diesen Fehler verursacht im Allgemeinen beim schreiben oder Lesen von USB auf Android?
- Welche Android-version verwenden Sie? Auch, was sind Sie versuchen zu kommunizieren, mit? Ich glaube, dass mit Zubehör-Modus (verwenden Sie Android-Open-Accessory-Modus?) Sie benötigen ein host-Gerät kompatibel ist, wie die arduino-oder FT311D.
- Android 4.0.4. Ich kann die erste Verbindung einwandfrei, und es gibt keine solche Sache wie ein "kompatibles" Gerät - wenn Sie senden Sie die richtige Steuerung-Anfragen, das Telefon geht im Zubehör-Modus, wenn es unterstützt. Ein dialog erscheint auf meinem Handy, die besagt, dass es sieht ein Zubehör - nur Probleme mit dem halten der Verbindung.
- Oh, ok, warten Sie, es sieht ein Accessoire, was bedeutet, Ihr Telefon ist im host-Modus dann nicht, Zubehör-Modus richtig? Welches Gerät ist die Bereitstellung der Strom -, Telefon-zu-Gerät oder Einrichtung, die auf das Telefon?
- Nein, die Android-Dokumentation ist tatsächlich ein wenig verwirrend, mit der Terminologie. Es sieht ein Accessoire, das heißt, es geht in den Zubehör-Modus. Wenn Sie im Zubehör-Modus auf einem Handy, können Sie Durchlaufen
UsbAccessory
Objekte - Sie werden sehen, wie Sie im Zubehör-Modus. Das Gerät ist eine Art, wie ein Android-tablet (auch 4.0.4 glaube ich); es ist die Bereitstellung von Strom auf meinem Handy. Es ist die Kommunikation über Host-Modus. Dies alle funktioniert zunächst nur diese "bad file number", kommt schließlich. - Ok, ich habe mit Open Accessory Modus meist so dass ich versuche nur, um herauszufinden, mehr Einzelheiten zu sehen, wie viel ich mag in der Lage sein, um Ihnen zu helfen... Also es klingt wie Sie haben zwei android-Geräten reden, über USB zwischen einander, ein host, ein Accessoire? Ist das richtig? Und Sie sind immer die "bad file number" auf die Zubehör-android-Gerät?
- Das ist richtig. Das Host-Gerät nicht erscheinen zu sein irgendwelche Probleme.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich habe dasselbe problem in meinem code, und ich fand, dass es geschieht, weil Filedescriptors Objekt wurde GCed.
Ich das Problem gelöst, durch hinzufügen ParcelFileDescriptor Feld in Aktivität(oder Service).
Ich habe Ihre ersten code-snippet und den code, den Sie basierend auf, und letztere hat ParcelFileDescriptor Feld im Thread.
Ich denke, wenn Sie bei der Bearbeitung der code wie unten, es funktioniert gut.
Am Ende war es ein threading-Problem. Ich brauchte mehr richtig trennen, auch schriftlich, als auch, statt nur zu Lesen.
Landete ich mit dieser code als Grundlage.
OK, ein paar Dinge, die ich bemerkte, das schien einfach anders aus, was ich für Open Accessory Modus, wodurch ich folgte die Dokumentation für USB-Zubehör meist, so ist es sollte sehr ähnlich sein, ist, dass Ihr
mIn.read(buf);
solltemIn.read(buf, 0, 64);
soweit ich weiß.Außerdem sollten Sie deklarieren Sie in Ihrer Klasse Erklärungen
thread myThread;
. Dann in IhremBroadcastReceiver
nach dem erstellen der neuenFileInput/OutputStream
habenmyThread = new thread(myHandler, myInputStream);
folgte meinemmyThread.start();
.Nun bemerkte ich, dass Sie kommunizieren direkt mit der Benutzeroberfläche von deinem thread. Sie sollten einen handler statt, dass der thread mitteilen und dann wird wieder die Kommunikation in Ihrer Benutzeroberfläche, zumindest von dem, was ich gelesen hatte.
Hier ein Beispiel von meinem handler und thread:
Außerdem gibt es einige demo-open accessory application hier. Sie können helfen, mit Ihrem Verständnis von Zubehör-Modus.
Und auch gibt es bekannte Probleme mit einer Anwendung, die nicht dem Erhalt der BroadcastReceiver für
ACTION_USB_ACCESSORY/DEVICE_ATTACHED
programmgesteuert. Es wird nur erhalten Sie über die manifest-Datei. Finden Sie mehr auf dieser hier und hier.Ich eigentlich nicht testen, setzen die
dataReceived
variable in der Prozedur, und erst vor kurzem geändert, dass ein Teil von meinem code. Habe es getestet und es hat nicht funktioniert, so versuchen sich zu erinnern, was es war, dass ich gelesen hatte, ich glaube, es war nicht über Variablen, die die Kommunikation innerhalb des threads, sondern versuchen, etwas zu verwenden, wie.setText()
. Ich habe aktualisiert mein code, derdataReceived=true
im thread. Die Prozedur würde dann verwendet werden, für die Aktualisierung von Elementen auf der Benutzeroberfläche, wieTextView
s, etc.Thread
mRead
überlastung war ein guter Rat, ich sollte immer angeben, eine maximale, aber es hat nicht am Ende verändern Sie viel. Ich denke, dies kann ein hardware-Seite Thema....so schwer zu sagen.onCreate
.synchronized()
Befehl vor IhrenParcelFileDescriptor
in Ihrem BroadcastReceiver.StrictMode$InstanceCountViolation
, die anscheinend deaktivieren Sie den strikten Modus. Versucht, kein Glück entweder. Ich werde versuchen, Sie explizit zu deklarieren Berechtigungen für das Telefon ich bin mit der in der hardware und sehen, ob das hilft Dingen.