ProgressBar blocked while MediaPlayer is playing

I'm trying to make a circular progress of the MediaPlayer, so it's indeterminate while it's preparing and setting progress while it's playing.

I've tried a lot of ways, but this is my last one: I update the bar on a AsyncTask<Object, Object, Object> .

The class I'm using is CircularProgressView but I've tried to swap to ProgressBar and the behavior is the same :

public void startPlaying(final Audio audio, final CircularProgressView progress_view) {

    if (!isPLAYING) {
        progress_view.setIndeterminate(true);
        progress_view.setVisibility(View.VISIBLE);
        progress_view.startAnimation();
        isPLAYING = true;
        audioPlaying = audio;
        mp = new MediaPlayer();

        new AsyncTask<Object, Object, Object>() {
            @Override
            protected Object doInBackground(Object... objects) {
                try {
                    mp.prepare();
                    publishProgress((int)-1);

                    mediaFileLengthInMilliseconds = mp.getDuration();
                    mp.start();

                    while (mp != null && mp.isPlaying()) {
                        Thread.sleep(100);
                        publishProgress((int) (mp.getCurrentPosition()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return null;
            }

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                try {
                    mp.setDataSource(audio.getFile().getUrl());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        stopPlaying();
                        publishProgress((int)-2);
                    }
                });
            }

            @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                int value = (int)values[0];
                if (value == -1) {
                    progress_view.setIndeterminate(false);
                    progress_view.setMaxProgress(mediaFileLengthInMilliseconds);
                } else if (value == -2) {
                    progress_view.setVisibility(View.GONE);
                } else {
                    progress_view.setProgress((int) values[0]);
                    System.out.println("setting: " + values[0]);
                }
            }

            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);
            }
        }.execute();

    } else {
        isPLAYING = false;
        stopPlaying();
    }
}

on debug, the ProgressBar or CircularProgressView .setProgress() is called during the audio reproduction, but it remains blocked in indeterminate , but progress_view.setIndeterminate(false) is called as well, and it doesn't become indeterminate.

When the audio finishes, the ProgressBar or CircularProgressView gets 100% progress.

Any clue?

Thank you very much in advance.


EDIT:

as @Blackbelt suggested, I had to call mediaFileLengthInMilliseconds = mp.getDuration(); before publishProgress((int)-1);

but now this is the behavior:

https://drive.google.com/file/d/0B-V0KHNRjbE_b3hkbkwtTXhIeTg/view?usp=sharing


EDIT 2 : Log of mp.getDuration() and mp.getCurrentPosition() :

http://pastebin.com/g93V5X9F

or maybe this is more clear:

http://pastebin.com/kYm01Gpg

called on this part:

            @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                int value = (int)values[0];
                if (value == -1) {
                    progress_view.setIndeterminate(false);
                    progress_view.setMaxProgress(mediaFileLengthInMilliseconds);
                    Log.i("Stackoverflow:", "setMaxProgress to " + mediaFileLengthInMilliseconds);
                } else if (value == -2) {
                    progress_view.setVisibility(View.GONE);
                } else {
                    progress_view.setProgress((int) values[0]);
                    Log.i("Stackoverflow:", "setProgress to " + (int)values[0]);

                }
            }

EDIT 3 : I'm adding the new code, commenting out the functions setIndeterminate(boolean) and swapping into ProgressBar :

XML:

<ProgressBar
        android:id="@+id/progress_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="false"
        android:progress="40"
        android:visibility="gone"
        android:layout_alignTop="@+id/play_button"
        android:layout_alignLeft="@+id/play_button"
        android:layout_alignStart="@+id/play_button"
        android:layout_alignRight="@+id/play_button"
        android:layout_alignEnd="@+id/play_button"
        android:layout_alignBottom="@+id/play_button" />

Java :

public void startPlaying(final Audio audio, final ProgressBar progress_view) {

    if (!isPLAYING) {
        Log.i("Stackoverflow", "startPlaying called");
        audio.put("times_listened", audio.getTimes_Listened() + 1);
        audio.saveEventually();

        progress_view.setVisibility(View.VISIBLE);
        isPLAYING = true;
        audioPlaying = audio;
        mp = new MediaPlayer();

        new AsyncTask<Object, Object, Object>() {
            @Override
            protected Object doInBackground(Object... objects) {
                try {
                    mp.prepare();
                    mediaFileLengthInMilliseconds = mp.getDuration();
                    publishProgress((int)-1);


                    mp.start();

                    while (mp != null && mp.isPlaying()) {
                        Thread.sleep(100);
                        publishProgress((int) (mp.getCurrentPosition()));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return null;
            }

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                try {
                    mp.setDataSource(audio.getFile().getUrl());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mediaPlayer) {
                        stopPlaying();
                        publishProgress((int)-2);
                    }
                });
            }

            @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                int value = (int)values[0];
                if (value == -1) {
                    progress_view.setMax(mediaFileLengthInMilliseconds);
                    Log.i("Stackoverflow:", "setMaxProgress to " + mediaFileLengthInMilliseconds);
                } else if (value == -2) {
                    progress_view.setVisibility(View.GONE);
                } else {
                    progress_view.setProgress((int) values[0]);
                    Log.i("Stackoverflow:", "setProgress to " + (int)values[0]);

                    System.out.println("setting: " + values[0]);
                }
            }

            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);
            }
        }.execute();

    } else {
        isPLAYING = false;
        stopPlaying();
    }
}

EDIT 4 :

I'm calling progress_view.isDeterminate() and it's returning me true everytime. So I decided to do when modifying the progress:

 @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                int value = (int)values[0];
                if (value == -1) {
                    progress_view.setMax(mediaFileLengthInMilliseconds);
                    Log.i("Stackoverflow:", "setMaxProgress to " + mediaFileLengthInMilliseconds);
                } else if (value == -2) {
                    progress_view.setVisibility(View.GONE);
                } else {
                    if (progress_view.isIndeterminate()) // LOOK AT THIS
                        progress_view.setIndeterminate(false);
                    progress_view.setProgress((int) values[0]);
                    Log.i("Stackoverflow:", "setProgress to " + (int) values[0]);
                    Log.i("Stackoverflow", "Indeterminate state: " + progress_view.isIndeterminate());

                    System.out.println("setting: " + values[0]);
                }
            }

and the output is always:

Indeterminate state: true

*WHY ? * :'(


Probably you want to call mediaFileLengthInMilliseconds = mp.getDuration(); before calling publishProgress((int)-1); and not after, or not using that member at all, since you keep already the MediaPlayer as member, you could query directly it.

Edit

To fix the problem in your video, you have to use the following style style="@android:style/Widget.ProgressBar.Horizontal . With the circular ProgressBar , the setIndetermiate flag is ignored

链接地址: http://www.djcxy.com/p/88602.html

上一篇: NFC标准(NFC论坛,ISO / IEC,ECMA

下一篇: ProgressPar在MediaPlayer播放时被阻止