mediaplayer with a list of audio that load asynchronously - android

I have a Music Player application that should play music via online streaming. It has a list of audio titles, and a play button and progress bar. upon clicking on a list item, it executes an asyncTask which loads the datasource in the mediaplayer from url and prepares it.
heres the list item click listener:
leclistv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,int p, long arg3)
{
url=geturl(p);
new PrepareStream().execute(url);
}
});
the asynctask class:
class PrepareStream extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
progress.show();
}
#Override
protected String doInBackground(String... opath) {
try {
String url = new String(opath[0]);
mp.reset();
mp.setDataSource(url);
mp.prepare();
} catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace();}
return null;
}
protected void onProgressUpdate(String... progress) {
}
#Override
protected void onPostExecute(String file_url) {
btnPlay.setEnabled(true);
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
updateProgressBar();
progress.dismiss();
}
}
BUT this works only once. once when i click on any list item, it loads just fine and plays just fine. but for the second time if i click on any list item, it crashes - because an asyncTask can be used only once. is there any way to make it work each time? if not, is there an alternative way to do this?
P.S: i could do it in a simple way without using asynctask, but i had to use because the audio is loaded from the server so the prepare() takes time and therefore i need to show the progressDialog while its loading.

Simple explanation for media player and how to handle varies problem related to it..reference link
reference code from the above link
public class MyService extends Service implements MediaPlayer.OnPreparedListener {
private static final String ACTION_PLAY = "com.example.action.PLAY";
MediaPlayer mMediaPlayer = null;
public int onStartCommand(Intent intent, int flags, int startId) {
...
if (intent.getAction().equals(ACTION_PLAY)) {
mMediaPlayer = ... // initialize it here
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync(); // prepare async to not block main thread
}
}
/** Called when MediaPlayer is ready */
public void onPrepared(MediaPlayer player) {
//When Media prepare this method work and you start your player
player.start();
}
}

Related

Music played using asyncTask isn't stopping by using cancel

I am using a music in background of my activity. But when i am trying to cancel it its not working. The music is just continuously running until it finishes itself. Below is the code:
public class xx extends Activity
{ BackgroundSound mBackgroundSound = new BackgroundSound();
#Override
protected void onCreate(Bundle savedInstanceState)
{ ....
}
#Override
protected void onResume()
{
super.onResume();
mBackgroundSound.execute();
}
#Override
protected void onPause()
{
super.onPause();
mBackgroundSound.cancel(true);
}
and for options menu selection:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mBackgroundSound.cancel(true);
NavUtils.navigateUpFromSameTask(this);
return true;
case R.id.menu_Add:
{ mBackgroundSound.cancel(true);
Intent intent = new Intent(xx.this,yy.class);
intent.putExtra("flag", "add");
intent.putExtra("AddObj", "mm");
startActivity(intent);
break;
}
case R.id.menu_list_quote:
{
mBackgroundSound.cancel(true);
Intent intent = new Intent(xx.this,zz.class);
intent.putExtra("Obj", "nn");
startActivity(intent);
break;
}
}
//return true;
return super.onOptionsItemSelected(item);
}
and the asynTask:
public class BackgroundSound extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try
{
while( !isCancelled())
{
// FileDescriptor afd = openFd("cock_alarm.mp3");
MediaPlayer player = new MediaPlayer();
player.setDataSource(_musicFilePath);
player.prepare();
//player.setLooping(true); // Set looping
player.setVolume(100,100);
player.start();
// if(isCancelled())
// player.stop();
}
}
catch(Exception exp)
{
exp.printStackTrace();
}
return null;
}
}
Also, tried using for loop:
for(int i=0;i<100 && !isCancelled();i++)
and tried this inside try block of asyncTask:
if(isCancelled())
player.stop();
How am i going to solve it?
Instead of creating an AsyncTask, why not just create the MediaPlayer, and start it from your activity?
The MediaPlayer has its own threading logic built into it. You don't need to create a thread to manage the media player. You can read more here: http://developer.android.com/guide/topics/media/mediaplayer.html
In your activity, you could do the following:
private MediaPlayer mMediaPlayer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initalize the media player
mMediaPlayer = ... however you are initializing it ...;
// Set the listener so the media player can tell you when it is finished preparing
mMediaPlayer.setOnPreparedListener(this);
// Prepare the MediaPlayer asynchronously so that the UI thread does not lock up
mMediaPlayer.prepareAsync();
}
// You need to listen for when the Media Player is finished preparing and is ready
public void onPrepared(MediaPlayer player) {
// Start the player
player.start();
}
Then whenever you need to stop the player, simply call
mMediaPlayer.stop();
As, vogella explains it on his website:
"The AsyncTask does not handle configuration changes automatically, i.e. if the activity is recreated, the programmer has to handle that in his coding.
A common solution to this is to declare the AsyncTask in a retained headless fragment."
Look for full text to:
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html#androidbackground

Show progressbar while preparing music and increase music volume

I'm developing a radio app in which I have written MediaPlayer class inside Service,on button click starting and closing service to start and stop MediaPlayer.But in the project I'm facing two problems
1.I want to show progress while preparing music.although I have written code inside service so not able to show ProgressBar.
2.when we volume up then instead of music volume ringing volume is increasing.
I spent my lot time and didn't get success can any please tell me how to resolve this.Your valuable suggestion would be great appreciated.
PlayerService.java
public class PlayerService extends Service implements OnPreparedListener {
private MediaPlayer mPlayer;
public PlayerService() {
// TODO Auto-generated constructor stub
super();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
try {
mPlayer = new MediaPlayer();
mPlayer.setDataSource(Live.mUrl);
mPlayer.prepare();
mPlayer.setOnPreparedListener(this);
// mVisualizerView = (VisualizerView)
// findViewById(R.id.visualizerView);
// mVisualizerView.link(mPlayer);
// Start with just line renderer
// addLineRenderer();
} catch (Exception e) {
// TODO: handle exception
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mPlayer.start();
return 0;
}
#Override
public void onDestroy() {
mPlayer.release();
super.onDestroy();
}
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
}
}
Check out registerMediaButtonEventReceiver(ComponentName broadcastReceiver);
Define a BroadcastReceiver that handles ACTION_MEDIA_BUTTON. The recieved intent includes a single extra field, EXTRA_KEY_EVENT, containing the key event that caused the broadcast. You can use this key event to get which key was pressed.
This is just a sample code. syntax errors may be there.
// in onCreate of activity
registerMediaButtonEventReceiver(mediaReceiver );
// later somewhere in activity.
MediaButton_Receiver mediaReceiver = new MediaButton_Receiver();
class MediaButton_Receiver implements BroadcastReceiver {
void onReceive(Intent intent) {
KeyEvent ke = (KeyEvent)intent.getExtra(Intent.EXTRA_KEY_EVENT);
if (ke .getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
//Decrease your volume
}
// Similarly other key codes .......
}
}
Unregister the receiver in onPause() or onStop()

How to display progress dialog with media player ?

There is a problem in the following media player that plays the audio stream when you press play if the stream is not available there is no any response from the program, How can I solve this issue, try to make progress dialog, but the solution does not work, maybe I did something wrong, but when you click on the progress bar appears first and then immediately disappears without waiting to start playback of music.
setDataSource filed in advance a broken link, nothing has changed.
Code media player with progress dialog:
private class ProgressTask extends AsyncTask <Void,Void,Void>{
#Override
protected void onPreExecute(){
progressbar.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(Void... arg0) {
preload();
return null;
}
#Override
protected void onPostExecute(Void result) {
MPplay();
progressbar.setVisibility(View.GONE);
}
}
public void preload() {
releaseMP();
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
if(pdaStream.isChecked()){
Main_stream = "http://145.255.233.204:58000/radio_pda";
}else{
Main_stream = "http://145.255.233.204:58000/radio";
}
mediaPlayer.setDataSource(Main_stream);
} catch (IOException e) {
e.printStackTrace();
}
Log.d(LOG_TAG, "prepareAsync");
mediaPlayer.prepareAsync();;
}
public void MPplay(){
mediaPlayer.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
}
If you want to see when a video is ready for playback, use this callback. http://developer.android.com/reference/android/media/MediaPlayer.OnPreparedListener.html
onPrepared(MediaPlayer mp)
//Called when the media file is ready for playback.
If you would like to see when a video is 100% buffered, use this callback: http://developer.android.com/reference/android/media/MediaPlayer.OnBufferingUpdateListener.html
public abstract void onBufferingUpdate (MediaPlayer mp, int percent)

How to show ProgressDialog in Service

I have written an app that streaming a rtsp link.I have stream the url in my custom Service class.I want to show a proggresdialog while url is loading in the other words before start the music.Here is my codes;
public class MyMediaPlayerService extends Service implements OnCompletionListener{
private String path = "rtsp://someURL";
MediaPlayer mediaPlayer;
private ProgressDialog pd;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
}
public void surfaceCreated(SurfaceHolder holder) {
}
public void onCompletion(MediaPlayer _mediaPlayer) {
stopSelf();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (!mediaPlayer.isPlaying()) {
pd = new ProgressDialog(getApplicationContext());
pd.setMessage("Loading...");
pd.setCancelable(false);
pd.show();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(path);
mediaPlayer.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
mediaPlayer
.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
pd.dismiss();
mp.start();
}
});
}
return START_NOT_STICKY;
}
public void onDestroy() {
if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
mediaPlayer.release();
}
}
An also I am getting this errors on the log;
08-15 22:42:15.384: E/AndroidRuntime(1090): FATAL EXCEPTION: main
08-15 22:42:15.384: E/AndroidRuntime(1090): java.lang.RuntimeException: Unable to start service com.applogist.servis.MyMediaPlayerService#42417340 with Intent { cmp=com.applogist.standartfm/com.applogist.servis.MyMediaPlayerService }: android.view.WindowManager$BadTokenException: Unable to add window --
token null is not for an application
How to show a proggres dialog now?
It is advised to do that using Notification Service|Sending Notifications to the User by the official developer guide.
Also, if you need to play music in service, you need to do it in another thread.
Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.
However, if you insist to show a dialog and your music is played only after all is downloaded. I think you can use an dialog class which has an inner AsyncTask class. You can do the downloading task in the AsyncTask's doInBackground (Params... params) method and update the UI of the dialog by #Override protected void onProgressUpdate (Progress... values) of the AsyncTask.

Mediaplayer sometimes doesn't work

I'm running into the problem when I my play a video with my app using mediaplayer. Sometimes the video will play fine but other times there will just be a black screen. Its not the file that I'm calling the video from because I've tested on the same file and it works sometimes and sometimes doesn't. I feel this problem most commonly occurs after I have played a couple of videos. I usually get away with playing 3-4 before the problem starts. I was wondering what caused this and how I could fix it. My code is posted below.
public class FullImageActivity extends Activity implements SurfaceHolder.Callback, OnPreparedListener, OnErrorListener{
private static final String TAG = null;
MediaPlayer player;
SurfaceView surfaceview;
SurfaceHolder surfaceHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_image);
Intent i = getIntent();
long id = i.getExtras().getLong("id");
String path = i.getExtras().getString("videopath");
surfaceview = (SurfaceView)findViewById(R.id.surfaceview);
surfaceHolder = surfaceview.getHolder();
surfaceHolder.addCallback(this);
player = new MediaPlayer();
try {
player.reset();
player.setOnErrorListener(this);
player.setDataSource(path);
player.setOnPreparedListener(this);
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
player.setDisplay(holder);
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPrepared(MediaPlayer p) {
}
#Override
public boolean onError(MediaPlayer arg0, int arg1, int arg2) {
Log.i(TAG, "THERE WAS AN ERROR");
return false;
}
Thanks.
It's difficult to know exactly what the problem is.
A couple of things to try:
Make sure you are calling .release() in onPause(). This just ensures resources are released appropriately. You will need to reset things in onResume(), etc.
http://developer.android.com/reference/android/media/MediaPlayer.html#release()
Unless you really need to manipulate the surface, consider using a VideoView. It's not as fully featured as the MediaPlayer object but takes away some of the hassle of dealing with a SurfaceView, and manages the state for you.
http://developer.android.com/reference/android/widget/VideoView.html
The problem is, that your implementation relies on the assumption, that the activity gets destroyed, when the media player finished.
Yet it is possible, that your activity already exists, when your intent is fired up. In that case, your application skips onCreate(), so the media player can't be initialised.
You should override the onStart() method to launch the media player.

Categories

Resources