2014-02-15 36 views
3

prepareAsync方法中出现错误(1,-4)。文档指定这是“不正确的文件格式”(右?),但该文件是mp3格式。此外,当媒体播放器在另一个活动中被调用时,该软件的旧版本也会再现该文件。 我不知道如何解决问题,所以我在这里。AndroId MediaPlayer错误(1,-4)prepareAsync方法

该应用程序的代码如下所示:

SingletonMediaPlayer将管理在应用

public class SingletonMediaPlayer { 

    private static SingletonMediaPlayer instance; 
    private MediaPlayer mp; 
    private int buffer_state; 

    private SingletonMediaPlayer() { 
     Log.d("SMP","Creating new media player"); 
     this.mp = new MediaPlayer(); 
     this.buffer_state = 0; 
    } 

    public static SingletonMediaPlayer getInstance() { 
     if (instance == null) { 
      instance = new SingletonMediaPlayer(); 
     } 

     return instance; 
    } 

    public void play(String path, final TextView tv_messaging){    
     if(this.mp.isPlaying()){ 
      Log.d("SMP","Player is playing, now I'll stop and reset it"); 
      this.mp.stop(); 
      this.mp.reset(); 
      this.mp.release(); 
     } 

     Log.d("SMP","Set audio stream type"); 
     this.mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
     try { 

      Log.d("SMP","Set data source"); 
      this.mp.setDataSource(path); 
      Log.d("SMP","Prepare async"); 
      this.mp.prepareAsync(); 
      Log.d("SMP","Done!"); 
      tv_messaging.setText("Connecting to the server...please wait"); 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      tv_messaging.setText(e.toString()); 
      Log.e("SMP","IllegalArgumentException"); 
     } catch (SecurityException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      tv_messaging.setText(e.toString()); 
      Log.e("SMP","SecurityException"); 
     } catch (IllegalStateException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      tv_messaging.setText(e.toString()); 
      Log.e("SMP","IllegalStateException"); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      tv_messaging.setText(e.toString()); 
      Log.e("SMP","IOException"); 
     }catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
      tv_messaging.setText(e.toString()); 
      Log.e("SMP","Generic Exception"); 
     } 
    } 

    public void checkBufferState(final TextView tv_buffer_message){ 
     final SingletonMediaPlayer self = this; 

     Log.d("SMP"," Set on prepared listener"); 
     this.mp.setOnErrorListener(new OnErrorListener(){ 

      @Override 
      public boolean onError(MediaPlayer mp, int arg1, int arg2) { 
       // TODO Auto-generated method stub 
       return false; 
      } 

     }); 
     this.mp.setOnPreparedListener(new OnPreparedListener() { 
      public void onPrepared(MediaPlayer mPlayer) { 
       OnBufferingUpdateListener lis = new OnBufferingUpdateListener(){ 
        public void onBufferingUpdate(MediaPlayer mPlayer, int percent) { 
         Log.d("SMP","  Mediaplayer ready (preparation done). Inside buffer listener"); 
         self.buffer_state = percent; 
         if(tv_buffer_message != null){ 
          tv_buffer_message.setText(percent+"%"); 
         } 
        } 
       }; 

       Log.d("SMP"," Mediaplayer ready (preparation done). Installing buffer listener"); 
       mPlayer.setOnBufferingUpdateListener(lis); 
       Log.d("SMP"," Mediaplayer ready (preparation done). Starting reproduction"); 
       mPlayer.start(); 
       Log.d("SMP"," Mediaplayer ready (preparation done). Done!"); 
      } 
     }); 
    } 

    public int getBufferState(){ 
     return this.buffer_state; 
    } 
} 

我创建按钮dinamically用作单媒体播放对象,当点击该按钮时,应播放一个MP3。所以,就在使用循环创建按钮我有

final SingletonMediaPlayer mediaPlayer = SingletonMediaPlayer.getInstance(); 
mediaPlayer.checkBufferState(tv_sel_ep); 

比,每一个按钮,我有

button.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     mediaPlayer.play(link, Text_view_used_to_show_error); 
    } 
}); 

登录

02-15 14:35:24.165: D/dalvikvm(1415): GC_EXTERNAL_ALLOC freed 58K, 52% free 2633K/5379K, external 391K/517K, paused 87ms 
02-15 14:35:25.705: D/NetworkActivity(1415): Starting SelectEpisodeActivity 
02-15 14:35:25.995: D/SMP(1415): Creating new media player 
02-15 14:35:26.005: D/SMP(1415): Set on prepared listener 
02-15 14:35:28.745: W/KeyCharacterMap(1415): No keyboard for id 0 
02-15 14:35:28.745: W/KeyCharacterMap(1415): Using default keymap: /system/usr/keychars/qwerty.kcm.bin 
02-15 14:35:28.745: I/qqqqqqqqqqqqq(1415): qqqqqqqqqqqqqqqqqqqq 
02-15 14:35:29.235: D/dalvikvm(1415): GC_CONCURRENT freed 307K, 53% free 2669K/5639K, external 477K/989K, paused 8ms+12ms 
02-15 14:35:30.275: D/NetworkActivity(1415): Starting SelectEpisodeActivity 
02-15 14:35:30.415: D/SMP(1415): Set on prepared listener 
02-15 14:35:32.485: D/SMP(1415): Set audio stream type 
02-15 14:35:32.485: D/SMP(1415): Set data source 
02-15 14:35:32.785: D/SMP(1415): Prepare async 
02-15 14:35:32.785: D/SMP(1415): Done! 
02-15 14:35:32.885: W/MediaPlayer(1415): info/warning (1, 26) 
02-15 14:35:32.885: I/MediaPlayer(1415): Info (1,26) 
02-15 14:35:32.885: E/MediaPlayer(1415): error (1, -4) 
02-15 14:35:32.885: E/MediaPlayer(1415): Error (1,-4) 

编辑:新日志Dave答案后

02-16 14:35:11.265: D/dalvikvm(12723): GC_EXTERNAL_ALLOC freed 59K, 52% free 2633K/5379K, external 391K/517K, paused 133ms 
02-16 14:35:13.265: D/NetworkActivity(12723): Starting SelectEpisodeActivity 
02-16 14:35:13.405: D/SMP(12723): Creating new media player 
02-16 14:35:13.415: D/SMP(12723): Set on prepared listener 
02-16 14:35:17.365: D/SMP(12723): Set audio stream type 
02-16 14:35:17.365: D/SMP(12723): Set data source 
02-16 14:35:17.435: D/SMP(12723): Prepare async 
02-16 14:35:17.435: D/SMP(12723): Done! 
02-16 14:35:17.445: W/MediaPlayer(12723): info/warning (1, 26) 
02-16 14:35:17.445: E/MediaPlayer(12723): error (1, -4) 
02-16 14:35:17.465: I/MediaPlayer(12723): Info (1,26) 
02-16 14:35:17.465: E/MediaPlayer(12723): Error (1,-4) 

感谢您的帮助

回答

1

夫妇的事情。

1)如果您希望MediaPlayer之后仍然处于可用状态,则不应致电release()。 -4错误(如果我没记错的话)是无效的状态转换,并且尝试使用已发布的MediaPlayer应该产生完全错误。

2)当您创建MediaPlayer可以设置onPreparedonErroronBufferingUpdate听众一次。你现在在做什么似乎很尴尬和不必要。

3)当您遇到Android问题时,发布logcat输出。

如果你只是做#1,你可能会得到一些可行的结果。不过,在实际使用将调用回调的方法之前设置监听器是个不错的主意。

编辑:

private static SingletonMediaPlayer instance; 
private MediaPlayer mp; 
private int buffer_state; 
// Add a member for the TextView 
private TextView tv_buffer_message; 

private SingletonMediaPlayer() { 
    Log.d("SMP","Creating new media player"); 
    mp = new MediaPlayer(); 
    Log.d("SMP","Set audio stream type"); 
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
    mp.setOnErrorListener(new OnErrorListener(){ 
     @Override 
     public boolean onError(MediaPlayer mp, int arg1, int arg2) { 
      // YOU SHOULD REALLY DO SOMETHING HERE!!! IT COULD BE INFORMATIVE!!! 
      return false; 
     } 
    }); 
    Log.d("SMP"," Installing buffer listener"); 
    mp.setOnBufferingUpdateListener(new OnBufferingUpdateListener(){ 
     public void onBufferingUpdate(MediaPlayer mPlayer, int percent) { 
      Log.d("SMP","  Mediaplayer ready (preparation done). Inside buffer listener"); 
      buffer_state = percent; 
      if(tv_buffer_message != null){ 
       tv_buffer_message.setText(percent+"%"); 
      } 
     } 
    }; 
    Log.d("SMP"," Set on prepared listener"); 
    mp.setOnPreparedListener(new OnPreparedListener() { 
     public void onPrepared(MediaPlayer mPlayer) { 
      Log.d("SMP"," Mediaplayer ready (preparation done). Starting reproduction"); 
      mPlayer.start(); 
      Log.d("SMP"," Mediaplayer ready (preparation done). Done!"); 
     } 
    }); 
    buffer_state = 0; 
} 

// Remove the checkBufferState method and call the following in its place: 
public setBufferMessageView(TextView tv) { 
    tv_buffer_message = tv; 
} 

// getInstance, play, and getBufferState can stay the same, except remove the call to release 
+0

好吧,我说当我试着自己解决错误的release()方法;如果我删除它没有任何改变。我不明白第2点,什么是不必要的?第3点你是对的,当我发布问题时,我忘记了日志。 –

+0

如果您只是在创建“MediaPlayer”时添加侦听器,则不需要整个checkBufferState方法。在日志中注意准备好的监听器被多次设置(这可能是问题,因为准备好的回调调用开始)。我会编辑我的答案,以说明我相信会更好。 – Dave

+0

准备好的侦听器被设置一次,当我测试应用程序,由于获取日志文件我点击了一个按钮,没有链接,所以不可能我重现正确的错误。字符串'02-15 14:35:28.745:I/qqqqqqqqqqqqq(1415):qqqqqqqqqqqqqqqqqqqq'表示类似于“按下物理返回按钮”。我用你的指导原则更正了我的代码,但他仍然不起作用(请参阅新日志) –