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