2010-05-09 15 views
13

Tôi có một ứng dụng sẽ ghi và phát tệp âm thanh. Một số tệp âm thanh được tải xuống bằng cách sử dụng tải xuống http tiêu chuẩn đơn giản bằng cách sử dụng httpclient. Nó hoạt động như một sự quyến rũ trong một thời gian dài. Bây giờ tất cả của một đột ngột tôi không thể chơi các tập tin tôi tải về. Nó không thành công với ngăn xếp này. Tôi lưu trữ các tập tin trên SDCard và tôi gặp sự cố cả trên thiết bị cầm tay và thiết bị được kết nối USB.Android Mediaplayer: setDataSource issue cho tệp phương tiện đã tải xuống

Tôi đã kiểm tra xem tệp đã tải xuống có hay không trên máy chủ và tôi có thể phát tệp mà không gặp bất kỳ sự cố nào.

Đây là các đoạn mã tôi sử dụng (Tôi biết rằng recordFile là một đường dẫn hợp lệ cho tệp).

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

Đây là mã 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(); 
} 

Đây là ngoại lệ:

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) 

Tôi đã cố gắng tìm kiếm một số câu trả lời của lỗi bù đắp, nhưng không thực sự rõ ràng điều này vấn đề có thể là.

PS Tôi tải file với mã này:

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

Trả lời

3

Tôi đã tự giải quyết nó. Khi tôi đặt nó bình luận của tôi trên các giải pháp này là:

Khi tôi tái cấu trúc một phần của mã tôi đã thực hiện một lỗi đánh máy trên một mã băm tôi sử dụng để cho phép tải xuống và không. Thật không may tôi đã không có bắt thích hợp khi tôi tải về các tập tin buộc các tập tin được sản phẩm nào. Về cơ bản tôi gửi một tiêu đề yêu cầu xấu nếu bạn cố gắng lấy một tập tin mà không có một mã kích hoạt thích hợp.

Thủ phạm là ở đây:

 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 
    } 

Đối với trường hợp mã trạng thái trở lại một (ví dụ: tiêu đề yêu cầu xấu cho các truy cập bị chặn) là xấu. Những gì tôi bị mất là để nắm bắt các trường hợp của một con trỏ null ở đó và gây ra một mục nhập SQLite được cập nhật tuyên bố cho các ứng dụng tải xuống đã thành công nhưng nó đã không được.

Bài học kinh nghiệm: Luôn đặt trong các kiểm tra rỗng cho những trường hợp này ngay cả đối với nguyên mẫu. :-)

1

Trước tiên, hãy chắc chắn rằng thiết bị của bạn không được gắn kết. Android hoặc máy chủ lưu trữ có thể truy cập thẻ SD nhưng không thể đồng thời cả hai.

Thứ hai, không rõ lý do bạn đang sử dụng FileInputStreamgetFD(). Chỉ cần chuyển đường dẫn đến tệp trên thẻ SD đến số MediaPlayer (ví dụ: new File(Environment.getExternalStorageDirectory(), "yourfile.mp3")) và để trình phát mở tệp.

+0

Cảm ơn câu trả lời. Tuy nhiên, tôi đã tìm thấy sự cố không liên quan đến việc kiểm tra con trỏ null cho tệpOutputStream sau cuộc gọi. Tôi có một máy chủ web giữ các danh sách phát khác nhau đồng bộ hóa. Khi tôi tái cấu trúc một phần của mã tôi đã thực hiện một lỗi đánh máy trên một mã băm tôi sử dụng để cho phép tải xuống và không. Thật không may tôi đã không có bắt thích hợp khi tôi tải về các tập tin buộc các tập tin được sản phẩm nào. Về cơ bản tôi gửi một tiêu đề yêu cầu xấu nếu bạn cố gắng lấy một tập tin mà không có một mã kích hoạt thích hợp. Nó hiện đang được giải quyết và hoạt động tốt.:-) – Erik

+0

Tôi sử dụng getFD để đảm bảo rằng tôi có thể mở tệp và không phải lo lắng về các quyền. Tôi đã tìm thấy điều này là "an toàn hơn" khi làm việc với các tệp trên SDCard. – Erik

+0

Trên một số thiết bị (thực sự!) Trình phát đa phương tiện (sống trong một quy trình riêng) không thể truy cập các tệp riêng tư của ứng dụng. Tôi đã cố gắng phát tệp MIDI đã tải xuống bộ nhớ cache nội bộ của ứng dụng. Và trình phát đa phương tiện phát ra "(Quyền bị từ chối)" đối với bản ghi. – yuku

Các vấn đề liên quan