keep playing andorid media player when app killed and restart service - android

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.

Related

Android Preparing MediaPlayer from method call ErrorListener

I have discovered today after digging in a lot of problems of mediaPlayer that preparing from an activity by calling a method to a object to stream a song from URL make mediaPlayer to action onErrorListener
I have an activity with RecyclerView and when I click on a position I call this method:
musicController.playSong(position);
Now musicController is my object where I use MediaPlayer and have some buttons to action previous/next/seekbar.
The playSong method:
public void playSong(int position) {
this.currentPosition = position;
try {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(musicUrl.get(position));
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
The ideea is that I tryed 2 types of errorListener's:
1)
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("TEST", "Error");
playSong(currentPosition);
return true;
}
});
2)
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i("TEST", "Error");
try {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.setDataSource(musicUrl.get(currentPosition));
mediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
});
The first one will loop without stopping in logCat and the second one will trigger only 1 time.What is the difference between them ? Also, I have read that mediaPlayer need a Service to play on background but I don't really understand if really needs because my music still plays when I go to home screen.
if you want to stop music whenever
Home button pressed then u must want to override
onPause() for pause the music
and
resume the music u want onResume()

How to free memory used by VideoView

I have been having this issue for a while now.
I have a simple application that plays a playlist of videos within a videoview with a pause of a few seconds between them.
private final Runnable playNormalVideo = new Runnable() {
public void run() {
try {
final String filepath = ...;
viewVideo.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
onEndVideo(false);
return true;
}
});
viewVideo.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
onEndVideo(false);
}
});
viewVideo.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
background.setVisibility(View.INVISIBLE);
viewVideo.start();
}
});
viewVideo.setVideoPath(filepath);
viewVideo.setVisibility(View.VISIBLE);
viewVideo.requestFocus();
} catch (Exception e) {
String error = Utils.getStackTrace(e);
Utils.log(true, error);
}
}
};
and in my onEndVideo() function I make the background visible and check what video to play next and with a Handler i request to play it after x seconds.
My issue is the following :
Within a long run (approx 1 day) the background becomes invisible within a lot of seconds before the video starts. I don't understand why. If someone could help me get rid of this issue.
I also thought I should free memory between video plays but i don't seem to find how to do that.
Note : All the videos are saved on the device.
Thanks for any help.

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 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.

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