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)
Related
I have an activity that holds 2 instances of an ExoPlayer because I needed to create a queue that buffers the next video and I don't know which video is coming after the next one. I need those two players to also keep playing when my app is in the background. how can I achieve it? I tried Foreground Service but I saw that I need to click on the notification in order to continue to my activity. I need to go into the desired activity immediately.
I am currently in the process of writing a music app. Having read around the subject a bit its time to start writing a service and interfacing to it from my main activity. The Google Dec docs seem to indicate that the main activity should for the heavy lifting and the service should be streamlined as much as possible. My main activity does quite a lot of work to maintain a play list of songs. I've been trying (Without success) to pass that play list over to the service when the user clicks play. However, I'm now wondering if I need to do that.
My thinking is that I could let the main activity create the playlist. When user clicks play it sends the first track path, using a string, to the service which handles playing. The service also has the oncomplete listener. When it triggers it sends a broadcast back to the activity. When the broadcast is received it would launch the "next" function, which throws the next track to the service.
Would this work in theory?
I've worked it out for myself. For those that are interested my theory works perfectly. The activity handles the play, next, prev etc and playlists. The service receives instructions from the activity, and requests new instruction via broadcasts.
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 guess I still need to learn how Android apps flow. The title might not have been clear, so let me explain.
Situation:
I have a game which has a few different activities. For example, MenuActivity, GameActivity, and HowToActivity. The game starts at MenuActivity and plays a song set to loop. To have the same song play during MenuActivity and HowToActivity, uniterrupted, I have the song played from an implemented Application. If I press the home button, get a phone, or whatever, the song will continue to play. To prevent that, I need to stop the song when leaving the app.
Problem:
Currently, in MenuActivity, I have code to stop the song under the protected void onStop() function. This stops the song when leaving the app (Pressing the Home button, get a phone call), but it also stops the song when changing to another activity within the app, such as HowToActivity. So the question is, how can I tell the difference?
Jesse,
You need to have a service that will do the job of playing the song.
You can easily start the service from any of the activity of your application. Also the service can be stopped by any of the activity.
Hence in the activity onCreate(), you can start the song player service, that will play the song even if the activity dies and new activity starts. Once your application is done with the song playing, just call stopService().
I hope this will solve your issue.
~Rajan
Typically what happens is that people read the phone state using a PhoneStateListener:
http://developer.android.com/reference/android/telephony/PhoneStateListener.html
This is why so many apps need the READ_PHONE_STATE permission, they're making sure you aren't answering a call while the app goes off and continues to do something annoying. You can create a listener to check when things like this happen. You shouldn't really change the behavior of the home key (and can't!), but instead, you can always listen for things like onPause() and onStop().
You probably want a background service that actually does the music playing, etc.., and then you want to control this service from your actual app when you get lifecycle events inside activities. This makes your app a bit more modular (i.e., the thing that it's doing semantically is control the sound, download the stream, whatever), because the Activities control the UI, and the Services what happens behind the scenes.
Edit: tutorial for MediaPlayer from a service:
http://marakana.com/forums/android/examples/60.html
You might also want to look into using a wake lock, though it might not be strictly necessary.
Create a receiver to capture the following intent:
Intent.ACTION_CLOSE_SYSTEM_DIALOGS
This will be called when the Home screen of the phone is launched. So you can stop music at that time rather than stopping onStop() of Activity.
But this will not help if the user launch an app by pressing Home key long time.
So try to play different musics on different Screens.
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.