I have an instance of Android MediaRecorder running in a LifecycleService that has been bound to (bindService) and started (startService) by an activity.
The MediaRecorder is meant to be recording audio, even when the activity itself is in the background, due to other apps being open on the screen.
I'm aware that Android can sometimes close services under certain circumstances, such as it needing resources elsewhere.
Do I need to worry that Android could close a bound, started service like mine?
In the circumstance that concerns me, the service would still have a binding (the activity), and it would still had an active task (the recording would running), so based on this Stackover answer it would have two reasons not to disappear. But is that enough to guarantee that the service will survive?
If not, are there steps I can take to ensure the service never disappears? A wakelock in the service, for instance?
And out of curiousity, would the fact that the service is running MediaRecorder make any difference? Surely Android would know not to close an active MediaRecorder session, no?
Lastly, if services are arbitrarily closed despite all efforts to prevent it, is there a better class I could be using for my MediaRecorder, one that can keep running in the background even when the Activity/Fragment is in the background?
thanks
John
Related
I am just clearing up my Android doubts. So lets talk about Services, we use services when we have to perform an operation in the background. Lets say Playing Music in the background? Thats one of the most popular reasons why people use Services.
But i just used Mediaplayer in my Mainactivity and i used .start() method in onCreate of my activity. I then minimized the app, but guess what....music still plays. I open the app again, and the music is still playing. I then remove the app from recent apps, basically destroying it and the music stops. Basically the app performs how it is supposed to. Works PERFECT!
Then why do we use services at all for these kind of tasks?
Is there any scenario this code might create a problem? Or is this creating some memory leak or something?
When "minimized" the App continues to play music due to OS delay which allow an User to re-open the App without delay (due to a closure mistake?) because all remained in memory (even the Music) in the previous state.
But the memory is limited, and the CPU the same, so the OS could kill or freeze (using Doze) a background Activity in any moment without prompt User/Developer.
An Activity could be killed to claim Memory or freezed to save CPU cycles. In this situation only explicitely declared Background Services are allowed to run (however with some limitations and special-behaviours), so if you don't use Service your Music could stop in any moment in the future.
PS: even Background Service could be killed from OS, but this case is very-very rare and only on Extreme Low Memory situations.
It will play as long as Android lets it live. It may stop at any moment, usually after 10-20 minutes.
Consider using Foreground Service to playback music. It will last until user kills it, and also provides notification bar with control over the playback.
I am writing an application which can continuously monitor the input from mic, process it (Processing algorithms are written in C++) and save (log) or playback some events of interests. I am testing my app on Android L and Android M phones.
Application works fine as per my requirement with issue in following use case:
Turn the monitoring on
Press home button to send the app in background
Ensure device is not charging
Wait for some time
After some time (About 15 min) I get following message in logcat:
Suspending all threads...
To overcome the problem I tried following:
Hold wake locks (PARTIAL_WAKE_LOCK)
Use another level of thread spawning using an asynctask
Set FLAG_KEEP_SCREEN_ON in my activity
But none of them seem to work. On iOS I can achieve the desired functionality of this use case using highlighted flag in infoplist.
Is it possible to do something similar in Android? (I believe audio players already do something similar)
I hope this won't be a complete solution for you. But i will try to give a solution that will extend the lifetime of your application. First of all it is not possible to keep an application alive all the time. It is against the Android's rule, as when the system needs resource (for foreground app) it may stop your application. But you can extend the life time of an app by pushing the functionality into the service. Below is a solution for you.
Create an Activity which has 2 button to start and stop recording.
Create a Service and place a Public static variable as a flag set to either true or false.
In activity use the above static field to check if the service is active or not and enable or disable the start recording button according to it.
Use the button to start the service, inside the service acquire a Partial Wake Lock and start a Thread and do your recording. I hope you don't want to redeliver your Intent to the service as it is used to just start a thread for recording. You can use START_NOT_STICKY which restarts the service only if there is a pending start call. If you really wanted to redeliver your intent with recording and append it with the new one, i would say it is point less as you don't know when the service would be restarted and you may miss some recording at that time.
As you hold the partial wake lock it will continue to run until the Foreground app needs resource. As the service has higher priority than the background app.
In onDestroy()Stop the Thread by using the interrupt flag (Save recording too by checking the interrupt flag), set the public static field to FALSE and release the wake lock. You may start the recording from your activity when this is done.
By using FLAG_KEEP_SCREEN_ON in your activity you are just telling the system to "Keep the screen on when i am in this activity". If you hit home or switch to another activity it will not work. I hope games or apps like video players use this to keep the screen on.
I should also point that by keeping the Partial Wake Lock for longer time it may drain your battery considerably. Also you could advice your users to stay in the activity for continuous recording if you use the FLAG_KEEP_SCREEN_ON.
I would although advice to Start an Intent Service, acquire a partial wake lock and start recording. As it will stops the overhead for creating a new thread and starting or stopping it when needed.
Also in iOS, I think the system GC the APP for resources when your application shifts to the background. That's what i remember when i was learning iOS.
I hope my solution helped you little bit to extend your application's life time. Thank you
I am looking for a place to put my clean up code (e.g. releasing file handles, shutting down services).
Here is the scenario: I have an app with multiple activities and a service running in the background. The service accesses a lot of sensors and files. Thus, it must be stopped if the app is terminated by the user to prevent battery draining. However, the service must continue running while the app is in the background and/or the screen is turned off. I am looking for a place to stop the service in code. onDestroy() of my Activities seems not to be a good idea because Android may call it (even while my app is running) or may call it never at all.
Is there a good place for releasing used resources of an app when the user knowingly terminates it?
I've been looking through many questions about services, but I couldn't find one that suited me.
I need a service that both starts on BOOT_COMPLETED (not bound to an Activity) and runs ALL the time (therefore I can't user AlarmReceiver). I know it might drain my battery but so far I don't care. It is just for research purposes.
I have a service that monitors sensor's data. What I managed to do so far was: either start the service as a regular Activity, but it runs only for +-20s and it is stopped (I think the SO cuts it down to release its memory); or start a service that runs in foreground. It worked to keep the process running, however the class that actually runs the service somehow was not started, besides an annoying notification which is required.
The code I refered as the one that runs the service in foreground was taken from here:
Implement startForeground method in Android
I mean, how does an app like WhatsApp run constantly? Is it running in foreground? Because looking at Settings it seems the service is very stable, and it does not show any permanent notification, since it is not possible for a foreground service run without one.
( How to startForeground() without showing notification? )
Any advice?
You can use a WakeLock. But please remember, with great power comes great responsibility (to release them again and not over-use them).
But for now, just acquire a hefty WakeLock and only release it until you are done. This should keep your device's screen and CPU awake and allow you to do whatever it is you want to do.
I read Anndroid document - http://developer.android.com/guide/topics/media/mediaplayer.html
which said ".. you want it to continue playing while the user is interacting with other applications—then you must start a Service and control the MediaPlayer instance from there. "
But I found if I start a local a music file from an activity, then leave that activity, ( for example, press HOME key and interact with another app ), the music continues playing.
So, I don't understand " the "must start a Service" in document. Did I miss something?
This was not a big obstacle for my app at this moment. I am just wondering what's the potential problems could be if I do not use Service.( Services have longer lifespan, so the mediaplayer could be killed earlier, any others ? )
Our development is based on Android 2.2.
Thanks for any help in advance.
Big reason, if you are not using a service, users cannot listen to music outside of your app when the the activity gets paused or terminated. Technically you can make a music app but if your users cant listen to music when another app is in the foreground or the phone is in a different state(locked) it wont make for a very good app. You should take a look at the activity lifecycle for a deeper understanding of the process. Note that this behavior is by design for saving power, memory and cpu cycles.
It helps also not to think of services in the more traditional desktop dev usage. You want this thing to live even when your activity is not up and about.
For more about activity life cycles Managing the Activity Lifecycle
For the How
http://www.androidcompetencycenter.com/2009/01/basics-of-android-part-iii-android-services/
For the why
Why is it important to use Services for background tasks?
Playing the music in the Activity might be fine for now, but when Android is low on resources it might try to kill your Activity. When you add a service to an app, Android will try to keep that process alive as long as possible if it falls under certain criteria (such as playing music). Read over the Process Lifecycle section on Services:
http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle
The activity can get killed by Android or by the user and then the music would stop playing.