2014-10-30 73 views
1

保持模式开启/关闭后,我的Android应用程序无法再次播放音乐。Android开发:在“保持模式”开启/关闭后,MediaPlayer无法工作

我的代码在开头工作正常(歌曲的声音)。 但当用户按下保持按钮时,应用程序无法继续播放(保持后再次返回屏幕)。

通过调试我已经检查,当你按下挂机键(重新启动手机),你的内心onResume(明显)进入,但mediaPlayer.prepare()抛出java.lang.IllegalStateException(catch块捕获)与消息:prepareAsync称为状态0

onResume()后,我调用的方法play()和它抛出这些错误:

尝试在错误的状态下执行seekTo

错误(-38,0)

尝试调用getDuration没有有效的媒体播放器

错误(-38,0)

任何想法? :S

这是我的代码:Fragment.java

public class FragmentMediaPlayer extends Fragment implements OnSeekBarChangeListener { 

    private MediaPlayer mediaPlayer; 
    public TextView duration; 
    private double timeElapsed = 0, finalTime = 0; 
    private int forwardTime = 5000, backwardTime = 5000; 
    private Handler durationHandler = new Handler(); 
    private SeekBar seekBar; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     View rootView = inflater.inflate(R.layout.media_player, container, 
       false); 

     // initialize views 
     initializeViews(rootView); 

     return rootView; 
    } 

    public void initializeViews(View rootView) { 
     mediaPlayer = MediaPlayer.create(getActivity(), R.raw.song); 
     try { 
      mediaPlayer.prepare(); 
     } catch (IllegalStateException | IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     finalTime = mediaPlayer.getDuration(); 
     duration = (TextView) rootView.findViewById(R.id.songDuration); 
     duration.setText(String.format(
       "%d min, %d sec", 
       0,0)); 

     seekBar = (SeekBar) rootView.findViewById(R.id.seekBar); 

     seekBar.setMax((int) finalTime); 
     seekBar.setOnSeekBarChangeListener(this); 

     ImageButton playButton = (ImageButton) rootView.findViewById(R.id.media_play); 
     playButton.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         play(); 
        } 
      }); 

     ImageButton media_pause = (ImageButton) rootView.findViewById(R.id.media_pause); 
     media_pause.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         pause(v); 
        } 
      }); 

     ImageButton media_ff = (ImageButton) rootView.findViewById(R.id.media_ff); 
     media_ff.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         forward(v); 
        } 
      }); 

     ImageButton media_rew = (ImageButton) rootView.findViewById(R.id.media_rew); 
     media_rew.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         rewind(v); 
        } 
      }); 
    } 

    // play mp3 song 
    public void play() {   
     timeElapsed = mediaPlayer.getCurrentPosition(); 
     seekBar.setProgress((int) timeElapsed); 
     mediaPlayer.seekTo((int) timeElapsed) ; 
     mediaPlayer.start(); 
     durationHandler.postDelayed(updateSeekBarTime, 100); 
    } 

    // handler to change seekBarTime 
    private Runnable updateSeekBarTime = new Runnable() { 
     public void run() { 
      // get current position 
      timeElapsed = mediaPlayer.getCurrentPosition(); 
      // set seekbar progress 
      seekBar.setProgress((int) timeElapsed); 
      // set time remaing 
      //double timeRemaining = finalTime - timeElapsed; 
      duration.setText(String.format(
        "%d min, %d sec", 
        TimeUnit.MILLISECONDS.toMinutes((long) timeElapsed), 
        TimeUnit.MILLISECONDS.toSeconds((long) timeElapsed) 
          - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS 
            .toMinutes((long) timeElapsed)))); 

      // repeat yourself that again in 100 miliseconds 
      durationHandler.postDelayed(this, 100);   
     } 
    }; 

    // pause mp3 song 
    public void pause(View view) { 
     mediaPlayer.pause();  
     timeElapsed = mediaPlayer.getCurrentPosition(); 
    } 

    // go forward at forwardTime seconds 
    public void forward(View view) { 
     // check if we can go forward at forwardTime seconds before song endes 
     if ((timeElapsed + forwardTime) <= finalTime) { 
      timeElapsed = timeElapsed + forwardTime; 

      // seek to the exact second of the track 
      mediaPlayer.seekTo((int) timeElapsed); 
     } 
    } 

    // go backwards at backwardTime seconds 
    public void rewind(View view) { 
     // check if we can go back at backwardTime seconds after song starts 
     if ((timeElapsed - backwardTime) > 0) { 
      timeElapsed = timeElapsed - backwardTime; 

      // seek to the exact second of the track 
      mediaPlayer.seekTo((int) timeElapsed); 
     } 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     try { 
      mediaPlayer.prepare(); 
     } catch (IllegalStateException | IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     play(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mediaPlayer.pause(); 
    } 

    @Override 
    public void onStop() { 
     // Stop updates and Disconnect from LocationServices 
     mediaPlayer.stop(); 
     durationHandler.removeCallbacks(updateSeekBarTime); 
     super.onStop(); 
    } 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
     if(fromUser) { 
      mediaPlayer.seekTo(progress); 
      seekBar.setProgress(progress); 
     } 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStopTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 

    } 

这里是我的layout.xml:

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fillViewport="true" 
    android:orientation="vertical" > 

<LinearLayout 
    android:id="@+id/container" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center" 
    android:orientation="vertical"> 

    <TextView 
     android:id="@+id/songName" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:text="@string/play_text" /> 

    <TextView 
     android:id="@+id/songDuration" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" /> 

    <SeekBar 
     android:id="@+id/seekBar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_marginTop="30dp" 
     android:layout_marginBottom="30dp" 
     android:gravity="center_horizontal" 
     android:orientation="horizontal" > 

     <ImageButton 
      android:id="@+id/media_rew" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="14dp" 
      android:contentDescription="@string/rewind" 
      android:src="@android:drawable/ic_media_rew" /> 

     <ImageButton 
      android:id="@+id/media_pause" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="14dp" 
      android:contentDescription="@string/pause" 
      android:src="@android:drawable/ic_media_pause" /> 

     <ImageButton 
      android:id="@+id/media_play" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="14dp" 
      android:contentDescription="@string/play" 
      android:src="@android:drawable/ic_media_play" /> 

     <ImageButton 
      android:id="@+id/media_ff" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="14dp" 
      android:contentDescription="@string/forward" 
      android:src="@android:drawable/ic_media_ff" /> 
    </LinearLayout>  

</LinearLayout> 
</ScrollView> 
+0

后,我已看过一些帖子,我已经把这个在我的代码,并从法的play()quited mediaPlayer.start(),但仍然有同样的问题: mediaPlayer.setOnPreparedListener(新OnPreparedListener() { \t @覆盖 \t公共无效onPrepared(MediaPlayer的熔点){ \t mp.start(); \t} \t}); – 2014-10-31 12:12:32

+0

我检查了MediaPlayer状态图:http://developer.android.com/images/mediaplayer_state_diagram.gif 我在暂停()后调用start()。我错过了一些东西...... – 2014-10-31 12:21:03

+0

你不应该在'已暂停'状态中调用'prepare()'。只有'start(),stop(),seekTo()'在'Paused'状态下有效。在你的情况下,只需在'onResume()'中调用'play()'方法即可。 – 2014-11-03 15:28:13

回答

1

我认为此代码应解决您的问题。

public class FragmentMediaPlayer extends Fragment implements OnSeekBarChangeListener { 

    private MediaPlayer mediaPlayer; 
    public TextView duration; 
    private int timeElapsed = 0, finalTime = 0; 
    private int forwardTime = 5000, backwardTime = 5000; 
    private Handler durationHandler = new Handler(); 
    private SeekBar seekBar; 
    private boolean pausedFromButton = false; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     View rootView = inflater.inflate(R.layout.media_player, container, 
       false); 

     // Initialize different views from the layout 
     duration = (TextView) rootView.findViewById(R.id.songDuration); 
     duration.setText(String.format(
       "%d min, %d sec", 
       0,0)); 

     seekBar = (SeekBar) rootView.findViewById(R.id.seekBar); 
     seekBar.setOnSeekBarChangeListener(this); 

     ImageButton playButton = (ImageButton) rootView.findViewById(R.id.media_play); 
     playButton.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         play(); 
        } 
      }); 

     ImageButton media_pause = (ImageButton) rootView.findViewById(R.id.media_pause); 
     media_pause.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         pause(); 
        } 
      }); 

     ImageButton media_ff = (ImageButton) rootView.findViewById(R.id.media_ff); 
     media_ff.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         forward(); 
        } 
      }); 

     ImageButton media_rew = (ImageButton) rootView.findViewById(R.id.media_rew); 
     media_rew.setOnClickListener(new OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         rewind(); 
        } 
      }); 

     return rootView; 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     prepareMediaPlayer(); 
     play(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     //Not call pause because it's necessaty to distinguish between onPause() and when the user press the pause buttonn 
     mediaPlayer.pause(); 
    } 

    @Override 
    public void onStop() { 
     // Stop updates and Disconnect from Services 
     mediaPlayer.stop(); 
     durationHandler.removeCallbacks(updateSeekBarTime); 
     super.onStop(); 
    } 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
     if(fromUser) { 
      mediaPlayer.seekTo(progress); 
      seekBar.setProgress(progress); 
     } 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onStopTrackingTouch(SeekBar arg0) { 
     // TODO Auto-generated method stub 

    } 

    /** 
    * Prepare MediaPlayer and recover from bad status 
    */ 
    private void prepareMediaPlayer() { 
     mediaPlayer = MediaPlayer.create(getActivity(), R.raw.song); 
     finalTime = mediaPlayer.getDuration(); 
     seekBar.setMax(finalTime); 
     mediaPlayer.seekTo(timeElapsed); 
     mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 
      @Override 
      public void onPrepared(MediaPlayer mp) { 
       mp.start(); 
      } 
     }); 
     mediaPlayer.setOnCompletionListener(new 
       OnCompletionListener() {   
        @Override 
        public void onCompletion(MediaPlayer arg0) { 
         pausedFromButton = true; 
        } 
     }); 
    } 

    /** 
    * play mp3 song 
    */ 
    public void play() { 
     if(pausedFromButton) { 
      prepareMediaPlayer(); 
      pausedFromButton = false; 
     }  
     seekBar.setProgress(timeElapsed); 
     durationHandler.postDelayed(updateSeekBarTime, 100); 
    } 

    /** 
    * handler to change seekBarTime 
    */ 
    private Runnable updateSeekBarTime = new Runnable() { 
     public void run() { 
      // get current position 
      timeElapsed = mediaPlayer.getCurrentPosition(); 
      // set seekbar progress 
      seekBar.setProgress(timeElapsed); 
      // set time remaing 
      //double timeRemaining = finalTime - timeElapsed; 
      duration.setText(String.format(
        "%d min, %d sec", 
        TimeUnit.MILLISECONDS.toMinutes((long) timeElapsed), 
        TimeUnit.MILLISECONDS.toSeconds((long) timeElapsed) 
          - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS 
            .toMinutes((long) timeElapsed)))); 

      // repeat yourself that again in 100 miliseconds 
      durationHandler.postDelayed(this, 100);   
     } 
    }; 


    /** 
    * pause mp3 song 
    */ 
    public void pause() { 
     mediaPlayer.pause();  
     timeElapsed = mediaPlayer.getCurrentPosition(); 
     pausedFromButton = true; 
    } 

    /** 
    * go forward at forwardTime seconds 
    */ 
    public void forward() { 
     // check if we can go forward at forwardTime seconds before song endes 
     if ((timeElapsed + forwardTime) <= finalTime) { 
      timeElapsed = timeElapsed + forwardTime; 

      // seek to the exact second of the track 
      mediaPlayer.seekTo(timeElapsed); 
     } 
    } 

    /** 
    * go backwards at backwardTime seconds 
    */ 
    public void rewind() { 
     // check if we can go back at backwardTime seconds after song starts 
     if ((timeElapsed - backwardTime) > 0) { 
      timeElapsed = timeElapsed - backwardTime; 

      // seek to the exact second of the track 
      mediaPlayer.seekTo(timeElapsed); 
     } 
    } 


} 
相关问题