2010-05-09 9 views
13

Ho un'applicazione che registrerà e riprodurrà file audio. Alcuni file audio vengono scaricati utilizzando semplici download HTTP standard con httpclient. Ha funzionato come un fascino per molto tempo. Ora, all'improvviso, non riesco a riprodurre i file che ho scaricato. Fallisce con questo stack. Conservo i file su SDCard e riscontro il problema sia su un portatile che su un dispositivo USB collegato.Mediaplayer Android: problema setDataSource per file multimediale scaricato

Ho verificato che il file scaricato è freddo sul server e posso riprodurlo senza problemi.

Questi sono i frammenti di codice che uso (so che recordingFile è un percorso valido per il file).

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

ecco il codice lettore multimediale:

// 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(); 
} 

Qui è l'eccezione:

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) 

Ho provato cercando qualche risposta l'errore di offset, ma non è davvero chiaro cosa questo problema potrebbe essere.

PS Ho scaricare il file con questo codice:

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; 
    } 

risposta

3

L'ho risolto da solo. Come ho detto il mio commento sopra la soluzione era questa:

Quando ho refactored parte del codice ho fatto un refuso su un codice hash che uso per consentire i download e non. Purtroppo non ho avuto la cattura corretta quando ho scaricato il file forzando il file a essere vuoto. Fondamentalmente invio un'intestazione di richiesta errata se si tenta di recuperare un file senza un codice di attivazione appropriato.

Il colpevole era qui:

 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 
    } 

Per i casi in cui il codice di stato è tornato un così male (cioè intestazione di richiesta male per accessi bloccati). Quello che mi è mancato è stato catturare il caso di un puntatore nullo e questo ha causato l'aggiornamento di una voce SQLite sostenendo che il download era riuscito ma non lo era.

Lezione appresa: inserire sempre i controlli null per questi casi anche per i prototipi. :-)

1

Per prima cosa, assicurarsi che il dispositivo non è montato. O Android o il PC host possono accedere alla scheda SD, ma non entrambi contemporaneamente.

In secondo luogo, non è chiaro il motivo per cui si sta utilizzando un FileInputStream e getFD(). Basta passare il percorso del file sulla scheda SD allo MediaPlayer (ad esempio, new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")) e lasciare che il lettore apra il file.

+0

Grazie per la risposta. Eppure ho trovato il problema, che non era correlato alla ricerca di un puntatore nullo per fileOutputStream dopo la chiamata. Ho un server web che mantiene sincronizzate playlist diverse. Quando ho refactored parte del codice ho fatto un refuso su un codice hash che uso per consentire i download e non. Purtroppo non ho avuto la cattura corretta quando ho scaricato il file forzando il file a essere vuoto. Fondamentalmente invio un'intestazione di richiesta errata se si tenta di recuperare un file senza un codice di attivazione appropriato. Ora è risolto e funziona bene.:-) – Erik

+0

Io uso getFD per essere sicuro di poter aprire i file e non dovermi preoccupare delle autorizzazioni. Ho trovato che questo è "più sicuro" quando si lavora con i file sulla SDCard. – Erik

+0

Su alcuni dispositivi (davvero!) Il mediaplayer (che vive su un processo separato) non può accedere ai file privati ​​dell'applicazione. Ho provato a riprodurre un file MIDI scaricato nella cache interna dell'applicazione. E il mediaplayer emette "(Autorizzazione negata)" al logcat. – yuku

Problemi correlati