AsyncTask is not responding to every click? - android

I have some problem with Android AsyncTask.In the Fragment i use async task for streaming a audio from url. At first play button it executes without any problem but when i click to go to next song the UI skip the song when i click again in next button then its working fine. It means i have to click two times to execute next button functionality.Here is my async task class:
private class LodingToFetchMp3Url extends AsyncTask<Void, Integer, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setMessage("Loading...!");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected String doInBackground(Void... params) {
try {
mediaPlayer.setDataSource(Constants.musicArrayListConstants.get(position).getMp3FileUrl());
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
imgPlayPause.setBackgroundResource(R.mipmap.btn_pause_black);
} else {
mediaPlayer.pause();
imgPlayPause.setBackgroundResource(R.mipmap.btn_play);
}
primarySeekBarProgressUpdater();
super.onPostExecute(result);
}
}
primarySeekBarProgressUpdater(); method:
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int) (((float) mediaPlayer.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification, 100);
}
}
Next Button onClick :
else if (v.getId() == R.id.imgNext) {
if(Constants.dropsModelArrayListConstants.size() > position) {
position = position + 1;
mediaPlayer.pause();
mediaPlayer = new MediaPlayer();
lodingToFetchMp3Url.cancel(true);
lodingToFetchMp3Url = new LodingToFetchMp3Url();
lodingToFetchMp3Url.execute();
}
}

Related

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

Android MediaPlayer to show a progressdialog until the song is buffered

What i have: code that plays mp3 song from server. It is working correctly
What i am trying to do:
place a progress dialog until onPrepared() event is reached which is
not happening
I tried using progress dialog as we do in async task which is not
showing up.
Is there any other correct way to do this
This i am trying to do because UI hangs in case of low net connectivity, there is no problem in case of good connectivity
<------- Blah blah code---------->
..
..
..
play(<mp3url>);
public void play(String url) {
try {
//mediaPlayer.stop();
mediaPlayer.setDataSource(url);
if(pd.isShowing() && pd!=null){
pd.dismiss();
pd=null;
}
pd = new ProgressDialog(ActAtomicGodDetailTunesCategorySongs.this);
pd.setMessage("loading...");
pd.setCancelable(false);
pd.show();
mediaPlayer.prepare();
//mediaPlayer.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//mediaPlayer.start();
//mediaPlayer.prepareAsync();
//seekBarProgress.postDelayed(onEverySecond, 1000);
}
#Override
public void onPrepared(MediaPlayer arg0) {
// TODO Auto-generated method stub
duration = mediaPlayer.getDuration();
seekBarProgress.setMax(duration);
if(pd!=null && pd.isShowing()){
pd.dismiss();
}
mediaPlayer.start();
seekBarProgress.postDelayed(onEverySecond, 1000);
}
..
..
..
<------- Blah blah code---------->
You can use a text view(Text: Buffering) instead of using Progress Dialog.
public void playmusic(){
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
text_buffer= (TextView) findViewById(R.id.txt_buffer);
mediaPlayer.setDataSource(store);
text_buffer.setVisibility(View.VISIBLE);
//very important. you should do this prepareAsync();
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
text_buffer.setVisibility(View.GONE);//or you can use View.INVISIBLE
mediaPlayer.start();
playState=true; // This is boolean to check whether music plays or not
}
});

Run a thread in android after one thread completes its execution

I want run run a thread after one thread completes its execution.
Here I am using progress bar, after progress bar completes the method do1() should execute but when I am run the application the application force close.
here is my code..
public void onenc(View view) {
progressBar = new ProgressDialog(view.getContext());
progressBar.setCancelable(true);
progressBar.setMessage("Ecoding Text ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(100);
progressBar.show();
//reset progress bar status
progressBarStatus = 0;
//reset filesize
fileSize = 0;
new Thread(new Runnable() {
public void run() {
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = doSomeTasks();
// your computer is too fast, sleep 1 second
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
// close the progress bar dialog
progressBar.dismiss();
}
}
}).start();
Thread tt =new Thread(new Runnable() {
public void run() {
do1();
try {
Thread.sleep(1100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tt.start();
}
I have also tried AsyncTask but both run simultaneously.
Please help me I am a newbie in android.
Thanks in advance.
Update:
After AsyncTask
class MyFirstTask extends AsyncTask<String, Boolean, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
return null;
//Do Stuff
}
public void progressUpdate(Integer progress) {
new Thread(new Runnable() {
public void run() {
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = doSomeTasks();
// your computer is too fast, sleep 1 second
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
// close the progress bar dialog
progressBar.dismiss();
}
}
}).start();
}
#Override
protected void onPostExecute(Boolean result) {
//Call your next task
Thread tt =new Thread(new Runnable() {
public void run() {
do1();
try {
Thread.sleep(1100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tt.start();
}
}
Now not even a single thread is executing the application force closes
After Another Update
class MyFirstTask extends AsyncTask<String, Boolean, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
new Thread(new Runnable() {
public void run() {
while (progressBarStatus < 100) {
// process some tasks
progressBarStatus = doSomeTasks();
// your computer is too fast, sleep 1 second
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
progressBarHandler.post(new Runnable() {
public void run() {
progressBar.setProgress(progressBarStatus);
}
});
}
// ok, file is downloaded,
if (progressBarStatus >= 100) {
// sleep 2 seconds, so that you can see the 100%
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
// close the progress bar dialog
progressBar.dismiss();
}
}
}).start();
return null;
//Do Stuff
}
public void progressUpdate(Integer progress) {
}
#Override
protected void onPostExecute(Boolean result) {
do1();
//Call your next task
/* Thread tt =new Thread(new Runnable() {
public void run() {
do1();
try {
Thread.sleep(1100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
tt.start();*/
}
}
Now the function do1() executes before progress bar completes.
Finally Solved it....Here is the answer.
Hope it will help others
class MyFirstTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.show();
}
#Override
protected String doInBackground(String... params) {
int i=0;
while(fileSize<100)
{
fileSize=fileSize+1;
publishProgress(""+(int)(fileSize));
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
publishProgress(""+(int)(fileSize));
return null;
}
public void onProgressUpdate(String... progress) {
progressBar.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String result) {
progressBar.dismiss();
do1();
}
}
Don't use Thread() at all. Use AsyncTask as it makes life easier and implement the onPostExecute() method to call the next AsyncTask
class MyFirstTask extends AsyncTask<String, Boolean, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
//Do Stuff that takes ages (background thread)
for(int i=0;i<100;i++){
doStuff();
Thread.sleep(1000L); //sleep because I'm just tired
publishProgress(i);
Thread.sleep(2000L); //sleep some more
}
}
#Override
public void progressUpdate(Integer progress) {
//Update progress bar (ui thread)
progressBar.setProgress(progress);
}
#Override
protected void onPostExecute(Boolean result) {
//Call your next task (ui thread)
new MyNextTask().execute();
}
Start your first task
new MyFirstTask().execute();
You can simply use join() method.
Thread first = new Thread();
Thread secThread =new Thread();
first.start();
first.join();
secThread.start();
but do not do this on main thread.

How to get duration of video when it is recording-Android

I'm facing with a problem. I want to get duration of video when i 'm recording it.
I can get duration of video when it's finish by code
MediaPlayer mp = MediaPlayer.create(mContext, Uri.parse(video));
if(mp == null)
return -1;
int duration = mp.getDuration();
mp.release();
But i want to get duration everytime when i record video to update to progressbar.
Hope your reply!
private class PlaybackObserver extends Thread {
public void run() {
currentPosition = 0;
try {
while (!killObserverThread) {
Thread.sleep(1000);
currentPosition = (int) mediaPlayer.getCurrentPosition();
runOnUiThread(new Runnable() {
public void run() {
yourProgressBar.setProgress(currentPosition);
}
});
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
killObserverThread = false;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (task == null || !task.isAlive()) {
task = new PlaybackObserver();
task.start();
}
startPlaying();
}
add a private class for your UiThread to update your seekbar/progressbar. Then start it from onResume()

android radio streaming background and progress dialog

I am developing a Radio application in android that will stream from url and in background will show progress dialog loading streams but shows ANR. I am using service for mediaplayer to start and stop. Need help.I have used asynctask but can't get a solution.
MainActivity.class
button_Play.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
new DownloadTask().execute();
}
});
class DownloadTask extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute()
{
progressDialog = ProgressDialog.show(MainActivity.this , "Android Streaming
Player" , "Connecting to Stream..." , true , false);
Log.d("onPreExecute()----->" , "MainActivity.class");
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params)
{
Log.d("doInBackground()----->" , "MainActivity.class");
startService(new Intent(MainActivity.this , RadioService.class));
return null;
}
#Override
protected void onPostExecute(Void result)
{
Log.d("onPostExecute()----->" , "MainActivity.class");
progressDialog.dismiss();
super.onPostExecute(result);
}
}
Here is service class:
RadioService.class
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("onStartCommand------->", "RadioService.class");
try
{
Log.d("MediaPlayer--->TRY BLOCK", "MediaPlayer");
URL url2 = new URL("http://141.139.35.23:8000");
URLConnection urlConnection = url2.openConnection();
player.setDataSource(urlConnection.getURL().toString());
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.prepare();
Log.d("MediaPlayer--->TRY BLOCK AFTER ASYNC", "MediaPlayer");
player.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
Log.d("MediaPlayer--->ON PREPARED BEGINS", "MediaPlayer");
//mp.setOnErrorListener(MainActivity.this);
mp.start();
//mp.setOnErrorListener(this);
mp.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
Toast.makeText(getApplicationContext() , "Streaming started " , Toast.LENGTH_SHORT).show();
Log.d("MediaPlayer--->ON PREPARED ENDS", "MediaPlayer");
}
});
} catch (Exception e)
{
Log.i("Exception", "Exception in streaming mediaplayer e = " + e);
}
return START_STICKY;
//return super.onStartCommand(intent, flags, startId);
}
class Loading extends AsyncTask<Object, Object, Object>{
protected void onPreExecute(){
loadDialog.show();
}
#Override
protected Object doInBackground(Object... arg0) {
if(rFlag==false){
mediaPlayer = new MediaPlayer();
try{
url = "rtsp://ra.dio";
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.start();
} catch (Exception e) {
loadDialog.dismiss();
errmsg = "error";
// TODO: handle exception
}
while(rFlag==false){
mediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer arg0, int arg1) {
// TODO Auto-generated method stub
if(arg1 >= 98){
loadDialog.dismiss();
rFlag=true;
}
}
});
}
}
else if(rFlag==true){
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer=null;
rFlag=false;
}
return null;
}
#Override
protected void onPostExecute(Object result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// loaded
}
}

Categories

Resources