Android:MediaPlayer getDuration()和getCurrentPosition()具有NullPointerException

shi*_*ram 2 android nullpointerexception android-mediaplayer

创建一个MediaPlayer.特定类具有播放,暂停和恢复的功能.我正在尝试制作一个SeekBar能显示进度的东西. SeekBar要求作为maxlengthgetDuration()调用mediaplayer.getDuration()函数的函数获得的值并返回该值. SeekBar还需要从getCurrentPostion()函数中获得的当前位置的值.他们俩都回来了NullPointerException.

public class PlayMedia extends AsyncTask<Void, Void, Void>
    implements MediaPlayer.OnPreparedListener {


private MediaPlayer mediaPlayer;
int length;
int duration =0;
int currentPosition=0;
@Override
protected Void doInBackground(Void... params) {
    mediaPlayer = new MediaPlayer();
    try {
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"/Notate/"+MainActivity.filepath+".wav");
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.prepareAsync();
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {

    }
    return null;
}

@Override
protected void onPostExecute(Void result) {
    // TODO Auto-generated method stub
    super.onPostExecute(result);

   }
public int getDuration(){
    duration=mediaPlayer.getDuration();
    Log.d("Position",Integer.toString(duration));
    return duration;
}
public int getPresentDuration(){
    currentPosition=mediaPlayer.getCurrentPosition();
    Log.d("CurrentPosition",Integer.toString(currentPosition));
    return currentPosition;
}

@Override
public void onPrepared(MediaPlayer mp) {
    // TODO Auto-generated method stub
    if(mediaPlayer != null && mediaPlayer.isPlaying()){
        mediaPlayer.pause();
    }
    else if(mediaPlayer != null){
    mediaPlayer.start();
        }
    Log.d("Shivram", "Started Playing");

}
public void pause(){
    mediaPlayer.pause();
    length=mediaPlayer.getCurrentPosition();
    Log.d("Shivram","Paused");
}
public void resume(){
    mediaPlayer.seekTo(length);
    mediaPlayer.start();
    Log.d("Shivram","Resume");
Run Code Online (Sandbox Code Playgroud)

此Fragment类调用getDuration()创建异常的函数.

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    contentViewC = inflater.inflate(R.layout.fragment_fragment_b, container, false);
    final SeekBar seekBar;

    Button button = (Button) contentViewC.findViewById(R.id.button1);
    Button button2 = (Button) contentViewC.findViewById(R.id.button2);

    textToChange=(TextView)contentViewC.findViewById(R.id.textView1);
    final PlayMedia play=new PlayMedia();
    boolean pause=false;
    seekBar = (SeekBar) contentViewC.findViewById(R.id.SeekBar01);
    final int[] recordingDuration = new int[1];


    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (MainActivity.filepath != "Nothing") {
                if(play.getStatus()==AsyncTask.Status.FINISHED || play.getStatus()==AsyncTask.Status.RUNNING){
                    Log.d("Shivram-FragmentA", "Resume");
                    play.resume();

                }
                if(play.getStatus()==AsyncTask.Status.PENDING) {
                    play.execute();
                    recordingDuration[0] =play.getDuration();
                    seekBar.setMax(recordingDuration[0]);
                }
                Frequency getFreq=new Frequency();

              getFreq.execute();
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

stackTrace如下

01-13 21:44:15.182  16263-16263/com.example.shivram.notate E/AndroidRuntime? FATAL EXCEPTION: main
Process: com.example.shivram.notate, PID: 16263
java.lang.NullPointerException
        at com.example.shivram.notate.PlayMedia.getDuration(PlayMedia.java:43)
        at com.example.shivram.notate.FragmentC$1.onClick(FragmentC.java:66)
        at android.view.View.performClick(View.java:4456)
        at android.view.View$PerformClick.run(View.java:18465)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5086)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
        at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

Zak*_*Mak 5

您的问题区域在这里:

play.execute();
recordingDuration[0] =play.getDuration();
Run Code Online (Sandbox Code Playgroud)

无法保证AsyncTask在执行play.execute()后完成,因为这是一个Thread并且有自己的生命.因此,到那时您的MediaPlayer可能尚未初始化.尝试做部分:

recordingDuration[0] =play.getDuration();
seekBar.setMax(recordingDuration[0]);
Run Code Online (Sandbox Code Playgroud)

AsyncTask完成后台作业后.这应该在您的PostExecute方法中完成,并将解决异常.

但经过一番思考后,让我们意识到设计是错误的.您不需要在AsyncTask中维护MediaPlayer.

在您的活动中创建和管理MediaPlayer.让您的Activity实现OnPreparedListener.获取持续时间并通过onPrepared设置搜索条(查看下面的示例代码).只有在加载文件且播放器准备就绪后才能获得持续时间.

将"暂停"和"恢复"方法移动到"活动".AsyncTask主要用于完成长时间运行的任务.我在下面放了一个示例代码,应该有助于理解这一点.

public class MainActivity implements MediaPlayer.OnPreparedListener{

       private MediaPlayer mediaPlayer;
       boolean isReady;
       boolean paused;

       .....
       button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // Your logic to play, pause and initialize if needed
            if (!MainActivity.filepath.equals("Nothing")) {
               if(mediaPlayer != null && mediaPlayer.isPlaying()){
                    pause();
                    paused = true;
               }else if(paused){
                    resume();
                    paused = false;
               }
               // initialize again when player is stopped and another file is set
               // in that case put logic so that mediaPlayer is disposed and set to null 
               if (mediaPlayer == null){
                    initializeMediaPlayer();
               }


            }
        }
    });

    public void initializeMediaPlayer(){
            mediaPlayer = new MediaPlayer();
            try {
                mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                mediaPlayer.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath().toString()+"/Notate/"+MainActivity.filepath+".wav");
                mediaPlayer.setOnPreparedListener(this);
                mediaPlayer.prepareAsync(); // this is important so that UI is not stuck
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            } catch (IOException e) {

            }
    }

    // You need to listen for when the Media Player is finished preparing and is ready
    @Override
    public void onPrepared(MediaPlayer mp) {

        recordingDuration[0] = mediaPlayer.getDuration();

        //Called when the media file is ready for playback.
        isReady = true;
        // Start the player
        mediaPlayer.start();

    }

    public void pause(){

        if (mediaPlayer != null){
            mediaPlayer.pause();
            length=mediaPlayer.getCurrentPosition();
        }
    }
    public void resume(){

        if (mediaPlayer != null){
            mediaPlayer.seekTo(length);
            mediaPlayer.start();
        }
    }

   @Override
   public void onDestroy() {
       if (mediaPlayer != null) mediaPlayer.release();
   }


}
Run Code Online (Sandbox Code Playgroud)