Android: UI state dependent on serice (music player scenario) - android

I have an app which starts a service (using startService). This service performs something similar to playing music. It can be seen as an indefinite work which has to be stopped manually through my activity.
In my activity, I would like to use a "switch" to show the state of the service (running/not running). This is somewhat like a play/pause button on a music player.
When my activity is created, how would I create the UI (switch) to be consistent with the service state (running/not running)?
I don't this using saveInstanceState/restore... will work. My app could be killed completely and the service will service and I will not receive the instance state once started again.
I don't this using SharedPreferences/DB will work. My process could have been killed and at next start, the app would think that the service is running.
The only stable solution I've been able to come up with is to ask the service (maybe through binding) if it is doing work or not.
Would this work? How would you do this?

Binding to the service would work (we have this exact scenario with a background audio player and resolved it that way).
Be mindful that binding is asynchronous, though.

Related

How to Stop an Android Bound Service when the app is killed?

I have created a Service to implement a Music Player functionality and i am binding to the service.
Everything is working fine, the only problem is that when I kill my app while the song is playing, it kills the app, the notification also goes away but the song keeps on playing in the background without any notification, and to stop the audio, the app needs to be launched again.
But when i clear all tasks (kill all the apps) while the while a song is playing, it kills the app as well as the Song, which is correct.
I need a solution to stop the Audio when only my App is killed.
I have implemented onTaskRemoved() callback but the control doesn't always come there.
Can anyone help me here ? Thanks in advance.
Seems like the app is not disconnected fully from the service,
Try to call unbindService().
If your client is still bound to a service when your app destroys the client, destruction causes the client to unbind. It is better to practice to unbind the client as soon as it is done interacting with the service. Doing so allows the idle service to shut down.
Try looking at Managing the lifecycle of a bound service
https://developer.android.com/guide/components/bound-services#Lifecycle

Will Android ever arbitrarily close a bound, started service?

I have an instance of Android MediaRecorder running in a LifecycleService that has been bound to (bindService) and started (startService) by an activity.
The MediaRecorder is meant to be recording audio, even when the activity itself is in the background, due to other apps being open on the screen.
I'm aware that Android can sometimes close services under certain circumstances, such as it needing resources elsewhere.
Do I need to worry that Android could close a bound, started service like mine?
In the circumstance that concerns me, the service would still have a binding (the activity), and it would still had an active task (the recording would running), so based on this Stackover answer it would have two reasons not to disappear. But is that enough to guarantee that the service will survive?
If not, are there steps I can take to ensure the service never disappears? A wakelock in the service, for instance?
And out of curiousity, would the fact that the service is running MediaRecorder make any difference? Surely Android would know not to close an active MediaRecorder session, no?
Lastly, if services are arbitrarily closed despite all efforts to prevent it, is there a better class I could be using for my MediaRecorder, one that can keep running in the background even when the Activity/Fragment is in the background?
thanks
John

Trying to use same foreGroundNotification for 2 different services

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.

How to pausing and resume a service

I'm an android beginner, and unfortunately I could not find a satisfying answer for my service problem so far. I hope you can help me. I think that my question addresses a common task.
My situation is the following: I have implemented my own service that simply records GPS locations and stores them in a list. Once the service stops, it writes the data to a database.
This works well, but now the service should have some kind of "pause mode" where it stops recording and can be resumed later on. What would be the best way to implement this functionality?
So far I came up with two (admittedly not very satisfactory) ideas:
Implementing my own service lifecycle (start, stop, pause, resume) and binding the GUI to the service. Moreover, it seems that the binding happens asynchronously, which makes updating the GUI (enabling and disabling the start/stop controls) a little messy.
On pause, the service is stopped and the GPS locations are appended to some list in a singleton class. On resume, the service is started again and so on. The problem I see here is that the application might get killed while in pause mode and the data is lost.

How to communicate between Music Playback Service and UI Thread

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.

Categories

Resources