How to show ProgressDialog in Service - android

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.

Related

keep playing andorid media player when app killed and restart service

My program is a music player and my Android Media Player runs on the service. The problem here is that when killed my app, the service is restarted and my player starts to work from the beginning.
public class AudioPlayerService extends Service implementsMediaPlayer.OnPreparedListener {
private String url = "https://www.dev2qa.com/demo/media/test.mp3";
private MediaPlayer mediaPlayer = null;
private String TAG = "AudioPlayerService";
#Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"onCreate");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(true);
try {
mediaPlayer.setDataSource(url);
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.prepareAsync(); // might take long! (for buffering, etc)
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY_COMPATIBILITY;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
if(mediaPlayer.isPlaying()){
mediaPlayer.stop();
}
mediaPlayer.release();
}
#Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
}
My program is a music player and my Android Media Player runs on the service. The problem here is that when killed my app, the service is restarted and my player starts to work from the beginning.
If the User manually kills the App using the appropriate button in "Android Settings --> Apps --> your_app" page all its Activities, Threads and Services are killed because this is the User decision. Those killed things remain stopped in this case.
Only when the Service is killed by the System (to recover memory resources during LowMemory situation) the Service is automatically restarted if the STICKY flag is used (as you done).
It's not a good pratice to restart a Service that the User CHOOSED to kill, but you can do it using this: https://developer.android.com/training/scheduling/alarms (by creating an alarm every few seconds ahead in the time during the play execution)
Yes the player will starts again from the beginning when the Service is restarted if you don't manage this situation. So I think you have to save the current position somewhere and read it when the Service is restarted by the System or by the SchedulingAlarms of my previous link.

Keep radio playing in background

hi i'm trying to create a simple Online Radio i want to keep radio playing in bakcground and i know i should use Service but i don't how to use it please help me to make my app radio keep playing in background
this my code :
Button b_play ;
MediaPlayer mediaPlayer ;
boolean prepared = false;
boolean started = false;
String stream = "http://stream.radio.co/s98f81d47e/listen";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b_play = (Button)findViewById(R.id.b_play);
b_play.setEnabled(false);
b_play.setText("Loading");
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
new PlayerTask().execute(stream);
b_play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(started){
started = false;
mediaPlayer.pause();
b_play.setText("Play");
}else{
started = true;
mediaPlayer.start();
b_play.setText("Pause");
}
}
});
}
class PlayerTask extends AsyncTask<String, Void ,Boolean>{
#Override
protected Boolean doInBackground(String... strings) {
try {
mediaPlayer.setDataSource(strings[0]);
mediaPlayer.prepare();
prepared = true;
} catch (IOException e) {
e.printStackTrace();
}
return prepared;
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
b_play.setEnabled(true);
b_play.setText("Play");
}
}
#Override
protected void onPause() {
super.onPause();
if(started){
mediaPlayer.pause();
}
}
#Override
protected void onResume() {
super.onResume();
if(started){
mediaPlayer.start();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(prepared){
mediaPlayer.release();
}
}
}
Play the music from the foreground service.
Official Android documentation says:
that is a service that the user is actively aware of and is not a
candidate for the system to kill when low on memory. A foreground
service must provide a notification for the status bar, which is
placed under the Ongoing heading. This means that the notification
cannot be dismissed unless the service is either stopped or removed
from the foreground.
In your case a radio that plays music from a service should be set to run in the foreground, because the user is explicitly aware of its operation. The notification in the status bar might indicate the current song and allow the user to launch an activity to interact with the music player.
Here is an example

mediaplayer with a list of audio that load asynchronously

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

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

MediaPlay in Android MusicServices crashes when calling <MediaPlayer>.pause()

In our app we have a MusicService. Currently, it works perfectly fine in terms of playing music and stopping it, but that is from starting and stopping the service. We are calling it in other methods, but mp.pause() is crashing unless it is surrounded by a null checker. But when it checks for nulls it doesn't work at all. We had all this working earlier, but we started reformatting the way were doing it, because on Android 4.0 (ICS) the Music kept playing randomly even when we stopped it, but thats not the point anyway.
public class MusicService extends Service {
public static MediaPlayer mp;
#Override
public IBinder onBind(final Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
mp = MediaPlayer.create(this, R.raw.title_music);
mp.setLooping(true);
mp.setVolume(200, 200);
}
#Override
public int onStartCommand(final Intent intent, final int flags, final int startId) {
mp.start();
return 1;
}
#Override
public void onStart(final Intent intent, final int startId) {
}
public IBinder onUnBind(final Intent arg0) {
return null;
}
public static void onStop() {
mp.stop();
mp.release();
}
public static void onPause() {
if (mp!=null) {
mp.pause();
}
}
public static void onResume() {
if (mp!=null) {
mp.start();
}
}
#Override
public void onDestroy() {
mp.stop();
mp.release();
super.onDestroy();
}
#Override
public void onLowMemory() {
mp.stop();
mp.release();
}
}
We are using this to start the service in another activity:
intent = new Intent(this, MusicService.class);
startService(intent);
Without a log I can't really say with 100% certainty this is the issue, but it would appear that the pause method is being called while mp is in an invalid state. I suggest you change your onPause method so that it reads like so.
public static void onPause() {
if (mp!=null) {
if (mp.isPlaying())
mp.pause();
}
}
This will check to see if it is actually playing and will work for any state it is in, except an error state. At least according to the documentation.

Categories

Resources