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.
Related
I built a media playing app with controls in Fragments. The main Activity hosts all these Fragments. These Fragments keep a reference to the main Activity and call methods in the main Activity when there is a control change.
Now I need to prevent the main Activity from being gobbled up while it is in the background. What is the best way to make this possible?
Currently, my research makes it look like I will need to move just about all my main Activity code to a main foreground service and have forwarding methods in the main Activity. Is that how it needs to be done or is there an easier way?
What is the best way to make this possible?
It's not.
my research makes it look like I will need to move just about all my main Activity code to a main foreground service and have forwarding methods in the main Activity.
Your foreground service will be responsible for playing the music. Your UI (activity/fragments, Notification with MediaStyle, app widgets, etc.) will send commands to the service to tell it how to change the playback (pause, skip tracks, change volume, etc.).
Is that how it needs to be done
Yes, if you want your media playback to continue while your UI is in the background.
simply no
u can use background services for that
refer this video https://youtu.be/3EQWmME-hNA
I need to record uncompressed audio from the microphone continuously (hours) in an Android app, process the audio and visualise the result in a plot. If the app loses focus, the plotting can (and should) stop, but the recording and the analysis shouldn't.
I'm not sure I got the right steps, so this is the implementation I have in mind:
A RecordActivity handles the view, in particular plotting the results as they arrive and handling the button presses. A record button starts a RecordService
A RecordService service initialises an android.media.AudioRecord and on its AudioRecord.OnRecordPositionUpdateListener reads in the buffer, saves it to file and analyses its contents. The result of the analysis is stored.
The RecordService uses a PendingIntent to communicate the results of the analysis to the RecordActivity, which updates the plot.
When the users presses the stop button, RecordActivity kills the service by calling stopService.
My questions are:
Is it right to use a service for this or can I just use an activity?
Is it right to use a started service rather than a bound one?
What parts of this process should be handled by a different thread (or even process)? The AudioRecording? (The analysis obviously depending on the requirements). The entire service?
Should the service being a Foreground service?
In general, is this structure correct?
A Service is a good solution, what I don't understand is why you're using a PendingIntent. Maybe you should consider using LocalBroadcast and normal Intent
In this case, since the service is bound to the lifecycle of the Activity, I suggest to use a bounded Service :)
Well...it depends. If the AudioRecording implementation has its own thread (as I guess in Android), then it's not strictly required to use a thread. But if you write many datas to filesystem, it could be better to start a thread inside the service and handle your logic there (remember that services are not thread)
It depends by your design. If you pause your Service logic when the app goes to background, it's not necessary. But if you need your service even when the app goes in background, then it's better to use a foreground Service
In general, I believe it's a good solution
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
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.
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.