在网上下载一段代码,发现只能播放一首歌曲,再次回到前一界面点击播放老是崩溃,大家帮忙看看是什么原因啊?
个人觉得应该是哪块的资源没释放,但是一直没找到
Androidmediaplayer异常

解决方案 »

  1.   

    package ntc.com.util;import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.ArrayList;
    import java.util.List;
    import android.app.Service;
    import android.content.Intent;
    import android.media.MediaPlayer;
    import android.os.Binder;
    import android.os.Handler;
    import android.os.IBinder;
    import android.text.TextUtils;
    import android.text.format.Time;
    import android.util.Log;
    import android.widget.Button;
    import android.widget.ImageButton;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.Toast;/**
     * MediaPlayer does not yet support streaming from external URLs so this class
     * provides a pseudo-streaming function by downloading the content incrementally
     * & playing as soon as we get enough audio in our temporary storage.
     */
    public class StreamingMediaPlayer extends Service { private static final int INTIAL_KB_BUFFER = 96 * 10 / 8;// assume
    // 96kbps*10secs/8bits
    // per byte
    Time tm;
    private static final String TAG = "StreamingMediaPlayer"; private TextView textStreamed;
    private ImageButton playButton;
    private ProgressBar progressBar;
    // Track for display by progressBar
    private float mediaLengthInKb, mediaLengthInSeconds;
    private int totalKbRead = 0;
    // Create Handler to call View updates on the main UI thread.
    private final Handler handler = new Handler();
    private MediaPlayer mediaPlayer;
    private File downloadingMediaFile;
    private boolean isInterrupted;
    private String context;
    private int counter = 0;
    private static Runnable r;
    private static Thread playerThread;
    private LocalBinder localBinder = new LocalBinder();
    private MediaPlayer player;
    private boolean isPause = false; // 播放器是否处于暂停状态
    private boolean isSame = false; // 所点播歌曲是否是当前播放歌曲
    private Integer position = -1; // 设置播放标记
    private List<String> music_name; // 歌曲列表
    private List<String> music_path; public StreamingMediaPlayer()
    {}

    public StreamingMediaPlayer(String context, TextView textStreamed,
    ImageButton playButton, Button streamButton, ProgressBar progressBar) {
    this.context = context;
    this.textStreamed = textStreamed;
    this.playButton = playButton;
    this.progressBar = progressBar;
    } public void setStreamingMediaPlayer(String context, TextView textStreamed,
    ImageButton playButton, Button streamButton, ProgressBar progressBar) {
    this.context = context;
    this.textStreamed = textStreamed;
    this.playButton = playButton;
    this.progressBar = progressBar;
    }

    /**
     * Progressivly download the media to a temporary location and update the
     * MediaPlayer as new content becomes available.
     */
    public void startStreaming(final String mediaUrl, float mediaLengthInKb,
    long mediaLengthInSeconds) throws IOException { this.mediaLengthInKb = mediaLengthInKb;
    this.mediaLengthInSeconds = mediaLengthInSeconds; r = new Runnable() {
    public void run() {
    try {
    Log.i("downloadAudioIncrement", "downloadAudioIncrement");
    downloadAudioIncrement(mediaUrl);
    } catch (IOException e) {
    Log.e(getClass().getName(),
    "Unable to initialize the MediaPlayer for fileUrl="
    + mediaUrl, e);
    return;
    }
    }
    };
    playerThread = new Thread(r);
    playerThread.start();
    // new Thread(r).start();
    } /**
     * Download the url stream to a temporary location and then call the
     * setDataSource for that local file
     */
    public void downloadAudioIncrement(String mediaUrl) throws IOException {
    Log.d(TAG, " mediaUrl.replaceAll !");

    // URL url = new URL(mediaUrl.replaceAll(" ", "%20"));
    // HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            URLConnection conn = new URL(mediaUrl).openConnection();    
            conn.addRequestProperty("User-Agent","NSPlayer/10.0.0.4072 WMFSDK/10.0"); 
            conn.connect();  
            
    InputStream stream = conn.getInputStream();
    Log.d(TAG, "  conn.getInputStream !");
    if (stream == null) {
    Log.e(getClass().getName(),
    "Unable to create InputStream for mediaUrl:" + mediaUrl);
    } downloadingMediaFile = new File(context + "downloadingMedia.dat"); // Just in case a prior deletion failed because our code crashed or
    // something, we also delete any previously
    // downloaded file to ensure we start fresh. If you use this code,
    // always delete
    // no longer used downloads else you'll quickly fill up your hard disk
    // memory. Of course, you can also
    // store any previously downloaded file in a separate data cache for
    // instant replay if you wanted as well.
    if (downloadingMediaFile.exists()) {
    downloadingMediaFile.delete();
    } FileOutputStream out = new FileOutputStream(downloadingMediaFile);
    byte buf[] = new byte[16384];
    int totalBytesRead = 0, incrementalBytesRead = 0;
    do {
    int numread = stream.read(buf);
    if (numread <= 0)
    break;
    out.write(buf, 0, numread);
    totalBytesRead += numread;
    incrementalBytesRead += numread;
    totalKbRead = totalBytesRead / 1000; testMediaBuffer();
    fireDataLoadUpdate();
    } while (validateNotInterrupted());
    stream.close();
    if (validateNotInterrupted()) {
    fireDataFullyLoaded();
    }
    } private boolean validateNotInterrupted() {
    if (isInterrupted) {
    if (mediaPlayer != null) {
    mediaPlayer.pause();
    // mediaPlayer.release();
    }
    return false;
    } else {
    return true;
    }
    } /**
     * Test whether we need to transfer buffered data to the MediaPlayer.
     * Interacting with MediaPlayer on non-main UI thread can causes crashes to
     * so perform this using a Handler.
     */
    private void testMediaBuffer() {
    Runnable updater = new Runnable() {
    public void run() {
    if (mediaPlayer == null) {
    // Only create the MediaPlayer once we have the minimum
    // buffered data
    if (totalKbRead >= INTIAL_KB_BUFFER) {
    try {
    startMediaPlayer();
    } catch (Exception e) {
    // Log.e(getClass().getName(),
    // "Error copying buffered conent.", e);
    }
    }
    } else if (mediaPlayer.getDuration()
    - mediaPlayer.getCurrentPosition() <= 1000) {
    // NOTE: The media player has stopped at the end so transfer
    // any existing buffered data
    // We test for < 1second of data because the media player
    // can stop when there is still
    // a few milliseconds of data left to play
    transferBufferToMediaPlayer();
    }
    }
    };
    handler.post(updater);
    } private void startMediaPlayer() {
    try {
    File bufferedFile = new File(context, "playingMedia" + (counter++)
    + ".dat"); // We double buffer the data to avoid potential read/write errors
    // that could happen if the
    // download thread attempted to write at the same time the
    // MediaPlayer was trying to read.
    // For example, we can't guarantee that the MediaPlayer won't open a
    // file for playing and leave it locked while
    // the media is playing. This would permanently deadlock the file
    // download. To avoid such a deadloack,
    // we move the currently loaded data to a temporary buffer file that
    // we start playing while the remaining
    // data downloads.
    moveFile(downloadingMediaFile, bufferedFile);
    //
    Log.e(getClass().getName(),
    "Buffered File path: " + bufferedFile.getAbsolutePath());
    Log.e(getClass().getName(),
    "Buffered File length: " + bufferedFile.length() + ""); mediaPlayer = createMediaPlayer(bufferedFile); // We have pre-loaded enough content and started the MediaPlayer so
    // update the buttons & progress meters.
    mediaPlayer.start();
    startPlayProgressUpdater();
    } catch (IOException e) {
    Log.e(getClass().getName(), "Error initializing the MediaPlayer.",
    e);
    return;
    }
    } public boolean pausePlayer() {
    try {
    MediaPlayer media = getMediaPlayer();
    if(null !=media )
    {
    media.pause();
    return true;
    }

    return false;
    } catch (Exception e) {
    e.printStackTrace();
    return false;
    }
    }
      

  2.   

    public boolean startPlayer() {
    MediaPlayer media = getMediaPlayer();
    if(null !=media )
    {
    media.start();
    startPlayProgressUpdater();
    return true;
    }
    Log.d(TAG, " getMediaPlayer().start() !");
    return false;
    } public void stopPlayer() {
    MediaPlayer media = getMediaPlayer();
    try {
    if(null !=media )
    {
    media.stop();
    addforEnd();
    }
    } catch (Exception e) {
    e.printStackTrace();

    }
    } public void addforEnd()
    {
    try {
    deleteTmpFile(this.context, true);

    if (mediaPlayer.isPlaying()) {
    Runnable notification = new Runnable() {
    public void run() {
    startPlayProgressUpdater();

    }
    };
    handler.postDelayed(notification, 1000);
    }
    }
    catch (Exception e) {
    Log.d(TAG, " addforEnd" + e.getMessage());
    e.printStackTrace();
    }
    }

    private void deleteTmpFile(String filePath, boolean deleteThisPath)
    throws IOException{

     if (!TextUtils.isEmpty(filePath)) {  
                File file = new File(filePath);  
      
                if (file.isDirectory()) {// 处理目录  
                    File files[] = file.listFiles();  
                    for (int i = 0; i < files.length; i++) {  
                     deleteTmpFile(files[i].getAbsolutePath(), true);  
                    }
                }  
                if (deleteThisPath) {  
                    if (!file.isDirectory()) {// 如果是文件,删除  
                        file.delete();  
                    }
                }  
            }  
    }

    /**
     * 根据文件创建一个mediaplayer对象
     */
    private MediaPlayer createMediaPlayer(File mediaFile) throws IOException {

    MediaPlayer mPlayer = new MediaPlayer();
    mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
    public boolean onError(MediaPlayer mp, int what, int extra) {
    // Log.e(getClass().getName(), "Error in MediaPlayer: (" + what
    // + ") with extra (" + extra + ")");
    return false;
    }
    }); // It appears that for security/permission reasons, it is better to pass
    // a FileDescriptor rather than a direct path to the File.
    // Also I have seen errors such as "PVMFErrNotSupported" and
    // "Prepare failed.: status=0x1" if a file path String is passed to
    // setDataSource(). So unless otherwise noted, we use a FileDescriptor
    // here.
    Log.d(TAG, "FileInputStream !");
    FileInputStream fis = new FileInputStream(mediaFile);
    Log.d(TAG, mediaFile.getName());
    mPlayer.setDataSource(fis.getFD());
    Log.d(TAG, "FileInputStream id over!");
    mPlayer.prepare();
    Log.d(TAG, "FileInputStream over!");
    return mPlayer;
    } /**
     * 把缓存转化成mediaplay对象 Transfer buffered data to the MediaPlayer. NOTE:
     * Interacting with a MediaPlayer on a non-main UI thread can cause
     * thread-lock and crashes so this method should always be called using a
     * Handler.
     */
    private void transferBufferToMediaPlayer() {
    try {
    // First determine if we need to restart the player after
    // transferring data...e.g. perhaps the user pressed pause
    boolean wasPlaying = mediaPlayer.isPlaying();
    int curPosition = mediaPlayer.getCurrentPosition(); // Copy the currently downloaded content to a new buffered File.
    // Store the old File for deleting later.
    File oldBufferedFile = new File(context, "playingMedia" + counter
    + ".dat");
    File bufferedFile = new File(context, "playingMedia" + (counter++)
    + ".dat"); // This may be the last buffered File so ask that it be delete on
    // exit. If it's already deleted, then this won't mean anything. If
    // you want to
    // keep and track fully downloaded files for later use, write
    // caching code and please send me a copy.
    // Log.d(TAG, "bufferedFile.deleteOnExit() !");
    bufferedFile.deleteOnExit();
    moveFile(downloadingMediaFile, bufferedFile); // Pause the current player now as we are about to create and start
    // a new one. So far (Android v1.5),
    // this always happens so quickly that the user never realized we've
    // stopped the player and started a new one
    mediaPlayer.pause(); // Create a new MediaPlayer rather than try to re-prepare the prior
    // one.
    Log.d(TAG, "createMediaPlayer(bufferedFile) !");
    mediaPlayer = createMediaPlayer(bufferedFile);
    Log.d(TAG, "seekTo(curPosition) !");
    mediaPlayer.seekTo(curPosition); // Restart if at end of prior buffered content or mediaPlayer was
    // previously playing.
    // NOTE: We test for < 1second of data because the media player can
    // stop when there is still
    // a few milliseconds of data left to play
    Log.d(TAG, "mediaPlayer.start() !");
    boolean atEndOfFile = mediaPlayer.getDuration()
    - mediaPlayer.getCurrentPosition() <= 1000;
    if (wasPlaying || atEndOfFile) {
    mediaPlayer.start();
    } // Lastly delete the previously playing buffered File as it's no
    // longer needed.
    Log.d(TAG, "oldBufferedFile.delete !");
    oldBufferedFile.delete(); } catch (Exception e) {
    Log.e(getClass().getName(),
    "Error updating to newly loaded content.", e);
    }
    } private void fireDataLoadUpdate() {
    Runnable updater = new Runnable() {
    public void run() {
    float loadProgress = ((float) totalKbRead / (float) mediaLengthInKb);
    }
    };
    handler.post(updater);
    } private void fireDataFullyLoaded() {
    Runnable updater = new Runnable() {
    public void run() {
    transferBufferToMediaPlayer(); // Delete the downloaded File as it's now been transferred to
    // the currently playing buffer file.
    downloadingMediaFile.delete();
    }
    };
    handler.post(updater);
    } // TODO 这个方法应该可以控制歌曲的播放
    public MediaPlayer getMediaPlayer() { return mediaPlayer;
    } public void setCurrentTime(long musicLength) {
    String sTmp = ParseFunction.GetTimeForLocation(musicLength); this.textStreamed.setText(sTmp);
    Log.d(TAG, " current time" + sTmp);
    } public void startPlayProgressUpdater() {
    float progress = (((float) mediaPlayer.getCurrentPosition() / 1000) / mediaLengthInSeconds); progressBar.setProgress((int) (progress * 100)); if (mediaPlayer.getCurrentPosition() != mediaLengthInSeconds) {
    setCurrentTime(mediaPlayer.getCurrentPosition());
    } else {
    setCurrentTime(((long) (mediaLengthInSeconds)) * 1000);
    progressBar.setProgress(100);
    } if (mediaPlayer.isPlaying()) {
    Runnable notification = new Runnable() {
    public void run() {
    startPlayProgressUpdater(); }
    };
    handler.postDelayed(notification, 1000);
    }
    } public void interrupt() {
    isInterrupted = true;
    validateNotInterrupted();
    } /**
     * Move the file in oldLocation to newLocation.
     */
    public void moveFile(File oldLocation, File newLocation) throws IOException { if (oldLocation.exists()) {
    BufferedInputStream reader = new BufferedInputStream(
    new FileInputStream(oldLocation));
    BufferedOutputStream writer = new BufferedOutputStream(
    new FileOutputStream(newLocation, false));
    try {
    byte[] buff = new byte[8192];
    int numChars;
    while ((numChars = reader.read(buff, 0, buff.length)) != -1) {
    writer.write(buff, 0, numChars);
    }
    } catch (IOException ex) {
    throw new IOException("IOException when transferring "
    + oldLocation.getPath() + " to "
    + newLocation.getPath());
    } finally {
    try {
    if (reader != null) {
    writer.close();
    reader.close();
    }
    } catch (IOException ex) {
    // Log.e(getClass().getName(),
    // "Error closing files when transferring "
    // + oldLocation.getPath() + " to "
    // + newLocation.getPath());
    }
    }
    } else {
    throw new IOException(
    "Old location does not exist when transferring "
    + oldLocation.getPath() + " to "
    + newLocation.getPath());
    }
    } /**
     * 獲取service中的播放器对象
     * 
     * @return 播放器对象
     */
    public MediaPlayer getPlayer() {
    return this.player;
    } @Override
    public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);
    /**
     * 1.现在需要的就是做从PlayActivity里获取歌曲列表,和歌曲路径,歌曲手名 并存放到各个集合里 2.之后就是对对这些数组进行处理
     */
    music_name = new ArrayList<String>();
    music_path = new ArrayList<String>();
    String info = intent.getStringExtra("info");
    Toast.makeText(getApplicationContext(), "歌曲播放异常", Toast.LENGTH_SHORT)
    .show();
    player = new MediaPlayer();
    try {
    playMusic(info);
    } catch (Exception e) {
    Toast.makeText(getApplicationContext(), "歌曲播放异常",
    Toast.LENGTH_SHORT).show();
    e.printStackTrace();
    }
    } // 播放音乐
    private void playMusic(String info) throws Exception {
    if ("play".equals(info)) {
    if (isPause) {// 暂停后,继续播放
    player.start();
    isPause = false;
    } else if (isSame) {// 如果现在播放和与所点播歌曲时同一首,继续播放所选歌曲
    player.start();
    } else {// 点播某一首歌曲
    play();
    }
    } else if ("pause".equals(info)) {
    player.pause();// 暂停
    isPause = true;
    } else if ("before".equals(info)) {
    playBefore();// 播放上一首
    } else if ("after".equals(info)) {
    playAfter();// 播放下一首
    }
    } private void play() throws Exception {
    // TODO 获取歌曲路径 try {
    Log.i("playtest", "playtest");
    player.reset();
    player.start();
    } catch (Exception e) {
    e.printStackTrace();
    } } private void playBefore() throws Exception {
    if (position == 0) {
    position = music_name.size() - 1;
    } else {
    position--;
    }
    play();
    } private void playAfter() throws Exception {
    if (position == 0) {
    position = music_name.size() + 1;
    } else {
    position++;
    }
    play();
    } public class LocalBinder extends Binder {
    public StreamingMediaPlayer getService() {
    return StreamingMediaPlayer.this;
    }
    } @Override
    public void onDestroy() {
    super.onDestroy();
    } @Override
    public boolean onUnbind(Intent intent) {
    return super.onUnbind(intent);
    } @Override
    public IBinder onBind(Intent intent) {
    return localBinder;
    }
    }
      

  3.   

    一直提示
    06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.022: E/MediaPlayer(9284): error (-38, 0)
    06-06 13:42:49.022: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
    06-06 13:42:49.022: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.092: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
    06-06 13:42:49.092: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.092: E/MediaPlayer(9284): error (-38, 0)
    06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
    06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0)
    06-06 13:42:49.122: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
    06-06 13:42:49.122: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.122: E/MediaPlayer(9284): error (-38, 0)
    06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer
    06-06 13:42:49.152: E/MediaPlayer(9284): message received msg=100, ext1=-38, ext2=0
    06-06 13:42:49.152: E/MediaPlayer(9284): error (-38, 0)
    06-06 13:42:49.152: E/MediaPlayer(9284): Attempt to call getDuration without a valid mediaplayer