2010-05-09 3 views
13

Ich habe eine Anwendung, die Audiodateien aufnehmen und abspielen wird. Einige der Audiodateien werden mit einfachen Standard-HTTP-Downloads unter Verwendung von httpclient heruntergeladen. Es hat lange wie ein Zauber funktioniert. Jetzt kann ich die heruntergeladenen Dateien nicht mehr abspielen. Es schlägt mit diesem Stapel fehl. Ich speichere die Dateien auf der SD-Karte und erlebe das Problem sowohl an einem Mobilteil als auch an einem USB-Gerät.Android Mediaplayer: SetDataSource Problem für heruntergeladene Mediendatei

Ich habe überprüft, dass die heruntergeladene Datei ist cool auf dem Server, und ich kann es ohne Probleme spielen.

Dies sind die Code-Snippets, die ich verwende (ich weiß, dass RecordingFile ein gültiger Pfad für die Datei ist).

// inside the activity class 
    private void playRecording() throws IOException{ 
     File recordingFile = new File(recordingFileName); 
     FileInputStream recordingInputStream = new FileInputStream(recordingFile); 
     audioMediaPlayer.playAudio(recordingInputStream); 
    } 

Hier ist der Code-Media-Player:

// inside my media player class which handles the recordings 
    public void playAudio(FileInputStream audioInputStream) throws IOException { 
     mediaPlayer.reset(); 
     mediaPlayer.setDataSource(audioInputStream.getFD()); 
     mediaPlayer.prepare(); 
     mediaPlayer.start(); 
} 

Hier ist die Ausnahme:

E/MediaPlayerService( 555): offset error 
E/MediaPlayer( 786): Unable to to create media player 
W/System.err( 786): java.io.IOException: setDataSourceFD failed.: status=0x80000000 
W/System.err( 786): at android.media.MediaPlayer.setDataSource(Native Method) 
W/System.err( 786): at android.media.MediaPlayer.setDataSource(MediaPlayer.java:632) 
W/System.err( 786): at net.xxx.xxx.AudioMediaPlayer.playAudio(AudioMediaPlayer.java:69) 
W/System.err( 786): at net.xxx.xxx.Downloads.playRecording(Downloads.java:299) 
W/System.err( 786): at net.xxx.xxx.Downloads.access$0(Downloads.java:294) 
W/System.err( 786): at net.xxx.xxx.Downloads$1.onClick(Downloads.java:135) 

ich versucht habe, eine gewisse Antwort des Offsetfehler zu suchen, aber nicht wirklich klar, was diese Problem könnte sein.

PS lade ich die Datei mit diesem Code:

public FileOutputStream executeHttpGet(FileOutputStream fileOutputStream) throws ClientProtocolException, IOException{ 
     try {  
      // Execute HTTP Post Request 
      httpResponse = httpClient.execute(httpPost, localContext); 
      int status = httpResponse.getStatusLine().getStatusCode(); 

      // we assume that the response body contains the error message 
      if (status != HttpStatus.SC_OK) { 
       ByteArrayOutputStream ostream = new ByteArrayOutputStream(); 
       httpResponse.getEntity().writeTo(ostream); 
       fileOutputStream = null; 
      } else { 
       InputStream content = httpResponse.getEntity().getContent(); 

       byte[] buffer = new byte[1024]; 
       int len = 0; 
       while ((len = content.read(buffer)) > 0) { 
        fileOutputStream.write(buffer,0, len); 
       } 
       fileOutputStream.close(); 
       content.close(); // this will also close the connection 
      } 

     } catch (ClientProtocolException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
      fileOutputStream = null; 
     } catch (IOException e2) { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
      fileOutputStream = null; 
     } 
     return fileOutputStream; 
    } 

Antwort

3

Ich löste es auf eigene Faust. Wie ich es meinen Kommentar über die Lösung war:

Wenn ich Teil des Codes refaktoriert habe ich einen Tippfehler auf einen Hash-Code, den ich verwenden, um Downloads zu ermöglichen und nicht. Leider hatte ich nicht den richtigen Haken, als ich die Datei heruntergeladen habe und die Datei zwang, leer zu sein. Im Grunde sende ich eine schlechte Anfrage Header, wenn Sie versuchen, eine Datei ohne einen richtigen Aktivierungscode abzurufen.

Der Täter hier war:

 if (status != HttpStatus.SC_OK) { 
      ByteArrayOutputStream ostream = new ByteArrayOutputStream(); 
      httpResponse.getEntity().writeTo(ostream); 
      fileOutputStream = null; 
     } else { 
      InputStream content = httpResponse.getEntity().getContent(); 

      byte[] buffer = new byte[1024]; 
      int len = 0; 
      while ((len = content.read(buffer)) > 0) { 
       fileOutputStream.write(buffer,0, len); 
      } 
      fileOutputStream.close(); 
      content.close(); // this will also close the connection 
    } 

Für Fälle, in denen der Statuscode zurück kam ein so schlecht (das heißt schlechte Request-Header für gesperrte Zugriffe). Was ich verpasste, war, den Fall eines Null-Zeigers dort zu erfassen, und das verursachte, dass ein SQLite-Eintrag aktualisiert wurde, der behauptete, dass der Download erfolgreich war, aber das war er nicht.

Lektion gelernt: immer die Null-Checks für diese Fälle auch für Prototypen. :-)

1

Erstens, stellen Sie sicher, dass Ihr Gerät nicht montiert ist. Entweder Android oder der Host-PC kann auf die SD-Karte zugreifen, aber nicht beide gleichzeitig.

Zweitens ist es unklar, warum Sie eine FileInputStream und getFD() verwenden. Übergeben Sie einfach den Pfad zu der Datei auf der SD-Karte an die MediaPlayer (z. B. new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")) und lassen Sie den Player die Datei öffnen.

+0

Danke für die Antwort. Dennoch fand ich das Problem, das nicht nach dem Aufruf nicht für einen Nullzeiger für den fileOutputStream überprüft wurde. Ich habe einen Webserver, der verschiedene Wiedergabelisten synchron hält. Als ich einen Teil des Codes umstrukturiert habe, habe ich einen Tippfehler auf einen Hash-Code gemacht, den ich benutze, um Downloads zu erlauben und nicht. Leider hatte ich nicht den richtigen Haken, als ich die Datei heruntergeladen habe und die Datei zwang, leer zu sein. Im Grunde sende ich eine schlechte Anfrage Header, wenn Sie versuchen, eine Datei ohne einen richtigen Aktivierungscode abzurufen. Es ist jetzt gelöst und funktioniert gut.:-) – Erik

+0

Ich benutze die getFD, um sicher zu sein, dass ich Dateien öffnen kann und mich nicht um die Berechtigungen kümmern muss. Ich habe festgestellt, dass dies bei der Arbeit mit Dateien auf der SD-Karte "sicherer" ist. – Erik

+0

Auf einigen Geräten (wirklich!) Kann der Mediaplayer (der in einem separaten Prozess lebt) nicht auf private Anwendungsdateien zugreifen. Ich habe versucht, eine MIDI-Datei abzuspielen, die in den internen Cache der Anwendung geladen wurde. Und der Mediaplayer gibt an den Logcat "(Permission denied)" aus. – yuku