working on a podcast app I'm currently thinking how to implement a small player (which includes a progressbar for current time playing, play, pause, rewind and forward button) which will be displayed in several activities through my app.
For playing podcasts in the background I've already implemented a Service which takes care of the MediaPlayer and the currently played podcast.
What is the best method for updating a small player over several activities and be able to pause and move the currently played podcast?
Thanks in advance.
You're on the right track. Every Activity that can control or see the mediaplayer should bind to the running service. If you implement the Observer design pattern in your service. Then you can make direct calls to the service and perform callbacks from the service to your activity.
Please make sure you play your audio/video in the background in a seperate thread because a service and an activity run in the same thread.
For your progressbar i should implement a callback function like progress(int secondsFromStart, int totalTimeSeconds) that will be called immediately after binding the service. Then the UI could update it's progressbar until it reaches totalTimeSeconds or shenever some kind of pauze call was received from the service.
If you want to use the same Player widget in several activities, then you should try Fragments API. That will alow you to compose complex UI. All your Activities will become Fragments with minor changes in code.
Related
I'm making a MP3 player and I have ArrayLists of songs that need to be altered and added to, even while the player is not active or in the background.
Do I store these ArrayLists in the Service so it can update them when needed, or do I store them in the Activity so the UI can access them easier? I've seen tutorials doing it both ways, so I am confused on how to proceed.
I'm thinking that if an Activity is not visible or active, the Service cannot access them. So, all of the mp3 lists should be stored in the Service and bind the Activity to the Service so the UI can update?
A Service can access my other classes while the app is in the background, right?
In general you do all the background actions in the service. This means that all data/information that is necessary to do this action or is related to this action is also managed by the service.
Your activities should only work as view or control possibility of your service.
In your case for example the PlaylistActivity will ask the service for the current playlist and will just display it. (Only a view for the service).
The PlayerActivity will get the current song playing, the current progress (e.g. in seconds), and the playing state (started/stopped). This information will be displayed in a typical player interface. But it will offer also controls to start or stop the song, jump to next or previous song or e.g. fast forward/backward. If the user clicks these controls it is simply forwarded to the service. (A view and control for the service)
I am building a music player in android for which I am using bound services to create mediaplayer and do all the background operations like playing media and pause etc like this.
All the UI components in mediaplayer are implemented in activity and I need to communicate events like mediaplayer is ready, media is playing, paused etc from service to activity to make changes in UI accordingly. What would be best way to do that?
Broadcasts from service to activity for various states is one way to implement it.
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 have an activity and a service component in my application.
The intention is to let the service take care of preparing the SurfaceView and mediaplayer instance that needs a surface holder. My media is a video file.
Is it possible to create the surface view from within my service?
Can I call the following
surface = (MySurfaceView) findViewById(R.id.surface);
in my service component?
If I did that, i could then assign the surface.getHolder to the player instance's setDisplay().
The overall goal is to issue commands (play, stop, seek, etc) from the activity and have the service implement the control of the mediaplayer state.
I probably could put all the stuff in my activity, but when i rotate the device, i don't want to tear down the surface and recreate it in onConfigurationChanged(). Hence looking at using the service for my situation here.
Any ideas or solutions highly appreciated.
Thanks.
You could use an AsyncTask implementation instead of the service, and do
all the background work in its
doInBackground method (different
thread, won't bother the user
interface), while
all the UI-related work could be done
in the onPostExecute method (the UI
thread).
Update
Since you need your media to be played in a background thread (without possible interruptions by gui processes), the Service could be a choice for you. You'll also need an Activity though, to start, stop and control your service.
For how to implement this design, you can check out this MusicDroid Tutorial part 2.
Though, it's not mandatory, to use services for this task, #CommonsWare's solution is very elegant and handy.
#CommonsWare's streaming video test application, and this Audio/Video player sample don't use services.
If you want to start and stop Service from the Activity, try using the approach described in this example application. It worked for me.
The demo could be even downloaded. You will need this music file.
I am making a Radio application in Android. I am facing a peculiar problem. I know this could be as easy but just not able to figure out how to do this. I am sure somebody would have faced a similar problem earlier and I will get a solution here
I have a first page that displays the list of stations. Once I click on any of these stations, a new Activity is started that has a View that has Play, Pause, Stop controls. When this activity is started, I also immediately invoke a new Service using startSevice() method. All the media player handling is done in this Service.
Now, I have a requirement of showing a Progress Dialog (Buffering) before the actual Media play starts. To show that I am trying to create a ProgressDialog in the Service, but it is asking for a context to be passed, I suppose I need to pass the Context of the activity that has invoked this service, because when I pass the current Context to it, it throws an Error.
How to achieve this? Is there a way to get hold of the Context of the Activity that started the Service?
If not, what could be some other way to achieve this, that is showing the Buffering status while the Media has not started playing
Use Broadcast intents. Bind the service to the activity and broadcast the buffering progress at 1 second intervals to the activity. Create a receiver in the activity that receives the broadcast and translates it to the progress bar in the activity.
I have a question maybe you can answer: I'm streaming using a service, just the way you are, but when the buffering first starts, I'm not clear on how to capture when the audio starts playing so that I can remove the "buffering" notification. I tried OnBufferingUpdate but that has a percentage value the whether the audio is playing or not. Thanks.