在 android 中下载的 mp3 文件抛出 IOException

Downloaded mp3 file in android throwing IOException

我正在使用下面的代码从我的服务器下载一个 mp3 文件到 android

public class DownloadService extends IntentService {

    private int result = Activity.RESULT_CANCELED;
    public static final String RESULT = "result";
    public static final String NOTIFICATION = "!@#$%%^";

    public DownloadService() {
        super("DownloadService");
    }

    // will be called asynchronously by Android
    @Override
    protected void onHandleIntent(Intent intent) {
        Integer serverTrackId=intent.getIntExtra(Constants.INTENT_PARAM_SERVER_TRACK_ID, 0);
        String serverUrl=intent.getStringExtra(Constants.INTENT_PARAM_SERVER_TRACK_URL);
        String trackName=intent.getStringExtra(Constants.INTENT_PARAM_SERVER_TRACK_NAME);
        String filePath=intent.getStringExtra(Constants.INTENT_PARAM_ROOT_FILE_PATH);
        Integer localTrackId=intent.getIntExtra(Constants.INTENT_PARAM_LOCAL_TRACK_ID, 0);

        File output = new File(filePath+"/"+trackName);
        if (output.exists()) {
            result = Activity.RESULT_OK;
            publishResults(output.getAbsolutePath(), result);
        }
        else {

            InputStream stream = null;
            FileOutputStream fos = null;
            try {

                URL url = new URL(serverUrl);
                stream = url.openConnection().getInputStream();
                InputStreamReader reader = new InputStreamReader(stream);
                fos = new FileOutputStream(output.getPath());
                int next = -1;
                while ((next = reader.read()) != -1) {
                    fos.write(next);
                }
                // successfully finished
                result = Activity.RESULT_OK;


            } catch (Exception e) {
                e.printStackTrace();
                result = Activity.RESULT_CANCELED;
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                        result = Activity.RESULT_CANCELED;
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        result = Activity.RESULT_CANCELED;
                        e.printStackTrace();
                    }
                }
            }
            publishResults(output.getAbsolutePath(), result);
        }
    }

    private void publishResults(String outputPath, int result) {
try {
    FileInputStream fileInputStream = new FileInputStream(outputPath);

        Intent intent = new Intent(NOTIFICATION);
        intent.putExtra(FILEPATH, outputPath);
        intent.putExtra(RESULT, result);
        sendBroadcast(intent);
}catch(Exception e){
    e.printStackTrace();
}
    }
}

下载播放完成后,我尝试通过以下代码播放mp3文件

 if (trackPath != null) {
                FileInputStream fileInputStream = new FileInputStream(trackPath);
                mediaPlayer.setDataSource(fileInputStream.getFD());
            } else {
                AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.spacer_audio);
                mediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
            }
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
            mediaPlayer.setLooping(false);
            mediaPlayer.prepare();
            mediaPlayer.setVolume(1f, 1f);
            mediaPlayer.start();

我从 "mediaPlayer.prepare()"

中抛出 IOException

我尝试通过 android 默认音乐播放器播放下载的音乐文件,它显示 "cannot play this media"。

我试着将它复制到电脑上播放,我注意到原始曲目和下载的曲目有几 KB 的大小差异。

请帮我找出错误。

您使用InputStreamReader读取二进制文件,可能会产生一些意想不到的问题。我建议您改用 BufferedInputStream

BufferedInputStream reader = new BufferedInputStream(stream);
fos = new FileOutputStream(output.getPath());
int length = -1;
byte[] buffer = new byte[1024 * 8];
while ((length = reader.read(buffer)) != -1) {
    fos.write(buffer, 0, length);
}