OK, so I am trying to use the same notification for 2 different fore-ground Services.
I have a music player service, which plays music....duh.
I have a downloader service which downloads the music file.
I have tried the following so far :
I kept the music Player service non-foreground :
I observed that when the download service finished and its foreground status got finished, my static final mediaPlayer which was in the other service got GC'ed. Basically my whole music player service stopped. This is probably the expected behavior and this happens quite randomly, not right after downloader finishes.
I called startForeground() in both services :
In this case as as soon as either of the 2 services finished, the foreground notification vanished. Probably foreground status in both services was not achieved. In any-case, my music-player can still get GC'ed.
What I plan on doing :
Somehow, have the knowledge that the notification is showing and we should not call start-foreground rather just update it (if any of the 2 services is in foreground, the associated process can not get GC'ed, so in my opinion my music player is safe, even if the actual service is not in foreground, am I correct in assuming this ?)
Merge the 2 services (really wanna avoid this)
Would appreciate some advice :)
I think you should have a single service that runs in the foreground (when it needs to) and have that service hold instances of your player and down loader. They don't need to be services, they can just be plain objects This might be a variation of your option 2, but it seems like the right approach to me at least.
Related
I am just clearing up my Android doubts. So lets talk about Services, we use services when we have to perform an operation in the background. Lets say Playing Music in the background? Thats one of the most popular reasons why people use Services.
But i just used Mediaplayer in my Mainactivity and i used .start() method in onCreate of my activity. I then minimized the app, but guess what....music still plays. I open the app again, and the music is still playing. I then remove the app from recent apps, basically destroying it and the music stops. Basically the app performs how it is supposed to. Works PERFECT!
Then why do we use services at all for these kind of tasks?
Is there any scenario this code might create a problem? Or is this creating some memory leak or something?
When "minimized" the App continues to play music due to OS delay which allow an User to re-open the App without delay (due to a closure mistake?) because all remained in memory (even the Music) in the previous state.
But the memory is limited, and the CPU the same, so the OS could kill or freeze (using Doze) a background Activity in any moment without prompt User/Developer.
An Activity could be killed to claim Memory or freezed to save CPU cycles. In this situation only explicitely declared Background Services are allowed to run (however with some limitations and special-behaviours), so if you don't use Service your Music could stop in any moment in the future.
PS: even Background Service could be killed from OS, but this case is very-very rare and only on Extreme Low Memory situations.
It will play as long as Android lets it live. It may stop at any moment, usually after 10-20 minutes.
Consider using Foreground Service to playback music. It will last until user kills it, and also provides notification bar with control over the playback.
I read Anndroid document - http://developer.android.com/guide/topics/media/mediaplayer.html
which said ".. you want it to continue playing while the user is interacting with other applications—then you must start a Service and control the MediaPlayer instance from there. "
But I found if I start a local a music file from an activity, then leave that activity, ( for example, press HOME key and interact with another app ), the music continues playing.
So, I don't understand " the "must start a Service" in document. Did I miss something?
This was not a big obstacle for my app at this moment. I am just wondering what's the potential problems could be if I do not use Service.( Services have longer lifespan, so the mediaplayer could be killed earlier, any others ? )
Our development is based on Android 2.2.
Thanks for any help in advance.
Big reason, if you are not using a service, users cannot listen to music outside of your app when the the activity gets paused or terminated. Technically you can make a music app but if your users cant listen to music when another app is in the foreground or the phone is in a different state(locked) it wont make for a very good app. You should take a look at the activity lifecycle for a deeper understanding of the process. Note that this behavior is by design for saving power, memory and cpu cycles.
It helps also not to think of services in the more traditional desktop dev usage. You want this thing to live even when your activity is not up and about.
For more about activity life cycles Managing the Activity Lifecycle
For the How
http://www.androidcompetencycenter.com/2009/01/basics-of-android-part-iii-android-services/
For the why
Why is it important to use Services for background tasks?
Playing the music in the Activity might be fine for now, but when Android is low on resources it might try to kill your Activity. When you add a service to an app, Android will try to keep that process alive as long as possible if it falls under certain criteria (such as playing music). Read over the Process Lifecycle section on Services:
http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle
The activity can get killed by Android or by the user and then the music would stop playing.
I have got a list of Music Titles in a ListView.
I can click on each item to play the Music through a MediaPlayer in a Service.
Now I want to implement 2 Features:
Music ProgressBar which is showing the current position in the song
The service shall continue playing when Song is over with the next song in the list
So how can I update the UI from a background service?
(I know there are some solutions on Stackoverflow but they seem to me a little bit of an overkill to send a Broadcast each Second from the Service i.e.)
Do I have to use Binding? What is the benefit of Binding?
Right now I just start the service with an Intent (startService(intent)) which contains the Song path.
What about the 2nd question? How can I do that?
I guess you built the service by yourself. Thus you know how it is built and how to get access to a mediaPlayer reference. What you need to do is to transform your service into a bound service. Maybe you will want your service to be started via startService (otherwise the bound service won't survive your activity), but afterwards, you will have to bind to it from inside your activity.
Once you are bound, you will get a IBinder (that you will define) and will be able to export the mediaPlayer reference to the bound activity through this IBinder. Afterwards, everything is quite straightforward, plug a listener on the media player and update your UI (in the UI thread !).
Also, you will need your service to be put forward.
I was solving very similar issues, however, I did the mixing/playing part myself.
The code for the android player-service part is at -github-
For communication between application and the service (it should be a foreground service with a notification in status bar, otherwise it can be silently killed / paused quite frequently) I experimented with different approaches and ended up with
Activity -> Service - using Messenger
Service -> Activity / anything - using BroadcastReceiver
The code on github is not too big (less than 500 lines total including imports) to give you an inspiration...
Btw. it also shows a service binding that does not kill service on activity exit.
I'd like to know more about the setForeground() method in the Service class.
Can any one explain it in detail?
setForeground() is deprecated, and I think simply does not work on newer versions of Android. You want the newer startForeground() instead.
Quoting myself from one of my books:
However, some services will be missed
by the user if they mysteriously
vanish. For example, the default music
player application that ships with
Android uses a service for the actual
music playback. That way, the user can
listen to music while continuing to
use their phone for other purposes.
The service only stops when the user
goes in and presses the stop button in
the music player activity. If that
service were to be shut down
unexpectedly, the user might wonder
what is wrong.
Services like this can declare
themselves as being part of the
"foreground". This will cause their
priority to rise and make them less
likely to be bumped out of memory. The
trade-off is that the service has to
maintain a Notification, so the user
knows that this service is claiming
part of the foreground. And, ideally,
that Notification provides an easy
path back to some activity where the
user can stop the service.
To do this, in onCreate() of your
service (or wherever else in the
service's life it would make sense),
call startForeground(). This takes a
Notification and a locally-unique
integer, just like the notify() method
on NotificationManager. It causes the
Notification to appear and moves the
service into foreground priority.
Later on, you can call
stopForeground() to return to normal
priority.
What are the disadvantages of running services in Android in Foreground.??
I recently read that if you want your services to last longer and not get killed easily we need to run the service in foreground.
What you read is right. It depends on what you want to do with your application. If your service does something which should not be interrupted without explicit user-interaction you should start it as a foreground-service. This assures that the service won't get killed if more memory is needed by other applications. Also you have an ongoing notification displayed so that the user is aware of what is happening and you can provide functionality to your notification such as opening an activity when tapping on the notification etc. Examples for this may be a music player service or a download service. If you have a service which does not have to run necessarily after leaving the app you should choose a service started in background, so that the memory can be released if it is needed for other tasks. Some more information you can find here: http://developer.android.com/reference/android/app/Service.html