Service, Rebind or not bound at all? - android

Ok, so I have this problem. I have a service that plays a mp3 file. I can also pause and stop the mp3 by AIDL functions. That works perfect. I can press the homebutton an then restart the activity and I have still control over the service.
However, if I press the back key and then opens the activity I can't control the service anymore.
I think it should be possible to rebind to the control when restarting the activiy. But what's happening is that new instance of the service is started and I can't stop the mp3 that is playing. I can play a new mp3 however. What am I doing wrong?

I think I understand what you want to do. After starting the activity and starting the mp3 playback, you exit from the activity. Then next time you open it you want to bind to the existing service and not start another instance of the service.
To achieve this, you have to use a started activity, and then bind to it. That is, use startActivity(Intent) on press of button, then in the next line, do bindService(Intent, connection, Context.FLAG_AUTO_CREATE);. This binds the service, then you can unbind in onDestroy (recommended) or onPause. Also, as this is a started service, it does not get destroyed when unbind. You have to explicitly call stopService(Intent) or stopSelf() to stop this service.
In the onResume of your activity, you should check if service is running, and then bind to it again using the code: bindService(Intent, connection, 0);
The connection object is a registered ServiceConnection that is fired everytime you bind or unbind to the service.
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
}
public void onServiceDisconnected(ComponentName className) {
}
};
Also, you can send and receive messages from the activity, in your case the time of mp3 song play, using Messenger Service.
Refer to this link to learn more about using Messenger.
Hope this helps.

I think is should be possible to rebind to the control when restarting the activiy.
I am sincerely hoping you unbound from the service, since you should not go through onDestroy() of an activity without unbinding.
But what's happening is that new instance of the service is started and I can't stop the mp3 that is playing.
This suggests that you did indeed unbind from the service, but the service did not stop the music playback when it was destroyed.
What am I doing wrong?
Most music players are designed to allow playback after the user exits the activity. Hence, music players should not be using the binding pattern, because the binding pattern does not support the service continuing to run after the user exits the activity.
Instead, use the command pattern: call startService() to start up music playback, perhaps with Intent extras to control what gets played. Call stopService() to stop music playback. Here is a sample project that demonstrates this, with the actual music playback stubbed out (as I cover that in a different book).

This is quite an old question but I'm currently working with a related problem. What I've found is that Binding to a service is meant so other applications can also bind to your service and make use of its functionality.
That is an alright pattern, it might work for your application.
What I think you should do, since I cannot find a way to rebind to a service; is to check if the service is running (which could be accomplished easily through a static boolean in the service class that is changed to true when running and changed back to false when destroyed) and use that boolean to prevent the onCreate of your application to reinitiate a new service intent. You can then bind to it again and use its functions.
Also, if there's only a possibility of using 1 song at the time, you might want to change all these variables to statics so any bound application can influence its variables (think volume, etc.) and read from its variables as well (think time playing, title, etc.)
Hope this helps a bit!

Related

Advantages and Disadvantages of binding vs starting a service in android

Yes, I know this is a duplicate: Android Service : bind or start?. But as I commented there, the answer given is problematic.
In the Google Dev Tutorial, binding is recommended as ...would work well for a music application that needs to bind an activity to its own service that's playing music in the background. Whereas the SO answer I just linked to says that's the very kind of service I would need to start instead of bind to.
Now, I understand the argument for Navigation app, but clearly the score is not settled for things like music streaming. So will someone please clarify a bit more?
The fact that I can bind endlessly and start endlessly would suggest the two methods exist for a reason. More pointedly, for instance, why is music streaming a good example for either?
And again, my main question: What are the advantages and disadvantages concerning binding vs starting? In other words: compare and contrast bindService and startService.
Sorry for the repetitions, but I am trying to capture this as completely as possible so I may get really good answers.
As for as I worked & read stuff about bindService and startService I am explaining the following.
First of all they two have different life Cycle.
bindService(mIntent, mConnection, BIND_AUTO_CREATE);
If you just use bindService with BIND_AUTO_CREATE flag to create the service and bind, it will create a service for you and bind it to you. Once you unbindService the service life will be stopped. ie. Most probably in onStop phase of your main process. So you can use bindService to create and bind service if you need it only on demand and close when you don't require. Like the Navigation App as you mentioned. This won't follow regular Service lifeCycle of onCreate > onStartCommand
startService(mIntent);
bindService(mIntent, mConnection, 0);
If you want to run the service even if you come out of the Activity then you have to use startService and you can bind to it using bindService with flag like 0 or BIND_ABOVE_CLIENT (means, service is more important than the running client activity). Now you can bind to the service and unbind any number of time, but the service will keep on running (until you kill it). This follows onCreate > onStartCommand
Your confusion with music app is basically with the use of the app: in Google Dev they might have noted in aspect like when you close your activity the music stops and exits the app (like Youtube). [binding and unbinding is enough]
And the SO might have noted in aspect like the music should continue playing even after coming out of activity (like Google Play Music). [for this you have to start a service and run it forever]. You can stop the service by calling this.stopSelf() when you need or stopService from an activity.
So you can't say bindService is better citizen than the started service.
The service created with bindService won't run after stopping the activity.

Service OR IntentService playing audio after recording

I want to achieve following goals:
Record Audio
Send Audio to Server
Play Audio
I know that First 2 tasks are possible by Using Service as I've done that in one of the previous apps but when it comes to playing an audio file, it needs to be triggered from an Activity.
Because accessing Activity from Service can be achieved by using BroadcastReceiver but what about accessing method of a Service from an Activity?
So, now comes the question: Whether to go for Service itself for Playing the audio also(triggered from activity) OR to use IntentService.
Documentation says,
No easy or direct way to interact with user interface directly from IntentService.
and
Any tasks started using IntentService cannot be interrupted
I may want to stop recording ant time and play it any time.
Which would suit t he requirement best --> Service OR IntentService ??
Any suggestions will be highly appreciated.
I would use a Service rather than an IntentService for what you need.
In particular, use a bound Service which allows two-way communication between the Activity which binds to it and from the Service to the Activity.
The IntentService class is designed for one-shot operations using its own worker thread, once the work on the thread is complete, the thread terminates and the IntentService calls stopSelf() to terminate itself. This means any user interaction between the user (via an Activity) and an IntentService is problematic.
A bound Service on the other hand will exist until it is either explicitly stopped or untill the last bound component unbinds. This allows for longer term interaction.
For playback, the fact a Service runs on the UI thread isn't an issue if you use something like MediaPlayerwhich handles its own thread for playback purposes.
Further to this, if you use a bound Service, MediaPlayer and MediaController, you can control play, stop, pause, seek etc from the Activity.
EDIT: For further information see... Bound Services

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.

Passing media player object between activities

I wanted to know how to pass a MediaPlayer object between activities so that I can maintain a constant sound play through out the application.
You don't "pass a MediaPlayer object between activities".
You need to access MediaPlayer from a custom Service to play sound in the background, and have your activities interact with this service.
For interaction my personal preference is binding using AIDL. Whenever I tried to use simple intents and onStartCommand() it revealed insufficient for activity/service interaction (I work with audio too). But it could work for you.
With AIDL and binding, you could expose custom functions such as play(uri), pause(), rewind(), etc.... The MediaPlayer instance would be created in play(uri) if it isn't already instantiated, and released in your service's onDestroy().
You can even register a listener with a RemoteCallbackList to get notified about position changes or some other events. See the examples on the AIDL documentation. What's nice about this is that your service can detect when a listener unregisters. This way you can have a small timeout in the service before you call stopSelf(), if another listener (activity) doesn't register quickly. That's useful because you don't necessarily know if an activity pauses because the user pressed the home button, or because he's cycling from one activity to the other.
Yeah, it needs a little work ;)
Note: you still need to call startService() before binding, otherwise the service will stop whenever an activity unbinds.
Check below link
http://developer.android.com/guide/appendix/faq/framework.html#3

Control service in GUI

I am writing an app that uses a media player. I want to start the media player using the service so that the music can be played even if the application is closed (onDestroy is run). Should I use BindService (for control the service) and not unBinding that?
the life cycle of the Service would be a bit tricky, start at playing screen created and stopped when either the music is complete in background or music is stopped when the app is finished (onDestroy)
how should i implement my service to best fit the above case i need?
Should I use BindService (for control the service) and not unBinding that?
No. You should call startService() to start it and stopService() to stop it (e.g., when the user presses the Stop button).

Categories

Resources