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.
Related
I have Fragment which is basically a View that shows any incoming messages for a user. I want the create something that will check every 5 seconds for any new messages, and if found will append them to my ListView which holds the messages. My question is, from what I have read, a Service is the way to go with this. However, since I will be communicating with the app from this service I'd like to know which service I should use.
Should I be using a Foreground service, or just a standard Service?
My goal is that where ever the user is in my app, I will be able to receive some notification that a new message has come through and then perform a function when that happens.
I want to code this properly and according to best practices.
If you just want to call a method on your service when user is in your app, you just need to use a sticky service, but if you want to call this method even when user swipe your app away from recent apps you should use not_sticky service.
Foreground service are most used for cases that u don't want your task stop even for a second after swiping your app from recent apps e.g. playing music in background.
But in your case the best choice is to use postDelayed() and set 5 seconds delay for it and get rid of service.
I know this look like tons of question around SO. But it's not (although I can also be wrong).
I have a long running Service (running in a separate thread using blutooth socket pooling for data in a OBD2 adapter every 5 seconds).
This Service is running in the same process and is a Foreground Service.
The user start this Service through an Activity. It then connect to the Bluetooth device and start pooling and saving data to a SQLiteDataBase.
The user can then minimize the activity and do other stuff.
When he returns (if ever, he can stop the service through a notification area button) to the application it checks if the Service is running and if so, it starts another Activity which show the data that is being pulled from the OBD2.
My question is, between this visualization Activity and the Service should I use and by this I mean the recommended or the right one:
LocalBroadcast? This is actually what I am using. Every time the service pull some data, it sends a broadcast with the data everytime it was pulled. Then in the onReceive method call runOnUiThread to update the respective View.
Messenger? As far as I know (never used it) I should send a Messenger from the Activity to the Service (much like a Handler) and in the Service it should send the Messages with the data pulled. But from this I would get a RemoteObjectException if the Activity was destroyed (like I said, the user could just minimized the activity and then it got GCed). So, I would probably need a way of sending the Messenger to the Service every time the Activity gets created and check if it's ok to use the messenger form the Service every time (if that's even possible, I've never used this).
BindService? Should I bind to the service when I open the Activity and then get the data directly from methods in the Service? But this would probably mean I would have another thread in the Activity gets this data from the Service every time, right?
Handler? (for a moment now I realize don't know the difference between Messenger and Handler, should it be that "use Messenger when Service runs in another process and Handler otherwise)
I've seen/read a lot of answers here in SO and through the web in general.
But in the end I don't see a ultimate answer for my case. But I'm sorry if this is just because I couldn't figure it out.
Thanks in advance!
EDIT: forgot to mention, I would rather make use only support libraries and android framework stuff, I'm still learning Android and I want to understand what's happening within its own classes.
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 have been given multiple solutions to what I thought would be a common scenario. Unfortunately, none seem to work as expected.
I have created a pretty simple android game. The users can invite friends to play and there are a few activities they are routed through during the game lifecycle. All turns and data is stored in a remote server which is exposing the data through web services. Every time an invitation is sent, or the opponents complete their turn, the user is prompted via the service to play their turn.
The service prompts the user using a standard android notification telling them it's their turn. I don't want the service to poll the web service or present notifications while the user is viewing the game (they'll already know if it's there turn).
I have tried the following solutions without any success.
Start the service in the onPause method of the main activity and stop the service in the onResume method of the main activity.
Problem - Each time the user leaves the activity for another one the service starts. The user may be writing something or creating an invitation and they are prompted to take their turn.
Bind each activity to the service and set a boolean (running) flag in the same onPause/onResume methods of all activities.
Problem - This seems logical, but for some reason the service never presents a notification. This is likely user-error, but I'm not sure this is the correct solution anyway.
Start the service in the onPause method of all activities and stop the service in the onResume method of all activities.
Problem - Based on the toasts I'm presenting on the screen showing the state of the service this works as expected. The problem is the user is presented with notifications while the service is off. Apparently my toasts are misleading.
Any help is greatly appreciated. Sample code is not necessary, but would be appreciated if the solution is any more complex than the concept described above.
Thank you.
Don't use a service, use the Google Cloud Messaging and in the receiver of the broadcast, check the state of the game and then decide whether or not to show the notification. Polling is generally bad, uses data and battery unnecessarily.
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.