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

时间:2015-01-13 16:00:10

标签: android nullpointerexception android-mediaplayer

创建MediaPlayer。 特定类具有播放,暂停和恢复的功能。我正在尝试制作一个显示进度的SeekBarSeekBar要求maxlength的值从getDuration()函数中获取,该函数调用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");

此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();
            }
        }
    });

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)

2 个答案:

答案 0 :(得分:5)

您的问题所在:

play.execute();
recordingDuration[0] =play.getDuration();

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

recordingDuration[0] =play.getDuration();
seekBar.setMax(recordingDuration[0]);

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();
   }


}

答案 1 :(得分:1)

获取当前位置的Java代码:

mediaPlayer.getCurrentPosition();

获取持续时间Java代码:

 private int getAudioDuration() {
    FFmpegMediaMetadataRetriever fFmpegMediaMetadataRetriever = new FFmpegMediaMetadataRetriever();
    fFmpegMediaMetadataRetriever.setDataSource(MP3);
    fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ALBUM);
    fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_ARTIST);
    int duration = Integer.parseInt(fFmpegMediaMetadataRetriever.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION));
    Log.v(TAG, "getDuration= " + duration);
    fFmpegMediaMetadataRetriever.release();
    return duration;
}

Build.Gradle(:app)

dependencies {
    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-core:1.0.15'
    implementation 'com.github.wseemann:FFmpegMediaMetadataRetriever-native:1.0.15'
}