I am currently working on an Android project on which we have a audio recorder module.
I am using MediaRecorder and it's working as expected except in some annoying situations :
When a notification sound is triggered by Android, the MediaRecorder stops
When receiving a phone call and even if refusing the call, the MediaRecorder stops
When the screen goes off
mRecorder = new MediaRecorder ();
mRecorder.setAudioSource (MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat (MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile (mFileName3GP);
mRecorder.setAudioEncoder (MediaRecorder.AudioEncoder.AAC);
mRecorder.setAudioEncodingBitRate (96000);
mRecorder.setAudioSamplingRate (48000);
mRecorder.start ();
I obviously doesn't want the audio recording to still be running during a call but on other situations I'd like my app to still perform the recording normally.
I didn't find anything pointing towards a solution. However, I am thinking about wakelocks (for screen off) and AudioFocus (for notifications and incoming calls).
Any advice ?
Thanks,
ant1
If this logic is embedded into an Acitivity it will be subject to the regular lifecycle changes in Android. Even if you prevent some normal operations from happening, you are then preventing/disrupting some of the expected behavior of the device. Maybe that is what you want, but there is another way.
You could use a Service instead:
http://developer.android.com/guide/components/services.html
http://developer.android.com/reference/android/app/Service.html
http://www.vogella.com/tutorials/AndroidServices/article.html
This will run in the background, so will not be affected by normal life-cycle interruptions, but you can still communicate via BroadcastReceivers and Intents.
This requires a little extra work to handle all the communication between the two, and possibly some kind of notification for the user to pause/stop/restart recordings, or whatever makes sense in your case.
Update:
Found this article on the Android docs which imply that you should be trying to pause and start your recording along with the activity pausing and starting:
http://developer.android.com/guide/topics/media/audio-capture.html
Maybe this can help too. One comment mentioned that the microphone stops input when you make/receive a call. Maybe there are built in limitations to what you are trying to do:
Pause and Resume Audio recording in Android
Related
I am developing a video call app, and all of my camera, networking, encoding, decoding and audio are running in my activity.
The main problem is that whenever the user locks their screen or switches apps, the activity is shut down and I lose the call.
I've tried wakelocks, notifications, foreground services, nothing keeps my activity alive past Android 10.
Any suggestions?
It is normal for the activity to disappear when the memory is insufficient. You need to use the foreground service to keep the program. Just like the music player, they all use the foreground service.
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
I have noticed an issue with my audio streaming app on Android 6.0 devices. Audio streaming is done via HLS over a network connection. Audio playback occurs in a foreground service with an active notification. What I've noticed is that when the app enters doze mode/app standby, the wifi connection is lost and playback pauses. My service is in the foreground and has an active notification which, according to the docs, should qualify my app to not be interrupted. I also acquire and maintain a Wifi Lock. I've read about whitelisting my app, however apps like Spotify don't request any special permissions to avoid this issue. Any thoughts or suggestions?
The recommended solution is to have separate processes, one for audio playback and for the UI. See this long thread for lots of details
Here's the relevant section from Ms Hackborn:
... have your foreground service run in a different process than the activity. From what I can see, this will work fine. I would be interesting in seeing if you get the desired behavior there.
Also this is actually our recommended practice for this situation -- if you have a long-running foreground service, it should be in a separate process from the activity, so it doesn't force all of the memory associated with the activity to be kept around. (This is also why this bug got through, all of our [Google] apps use this pattern.)
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'm trying to write an Android application which will allow users to listen to a radio station.
I have got the start and stop buttons to work and it plays the stream. If I press the home key and start doing other bits and pieces with the phone, the stream continues to play. This is how I want it to work.
Should I bother creating a service to play the stream, or is the method I already use good enough? What benefit would having it in a service bring? A lot of tutorials and examples online seem to use services but it seems to me it's just adding extra complications into the code. Or is it more efficient?
Regards,
David
You don't need to use a service, but your users may under normal use find that playback stops unexpectedly, it depends on the normal use case, so a Service is the best approach.
The reason is due to the lifetime of the Activity that your streaming object / media player is currently attached to.
At some point the system will completely release the Activity now that it is no longer visible to the user, and once GC happens playback will stop. This will happen depending on memory pressure and what other actions the user takes, such as launching other apps. Services are allowed a longer life span, in general they will be released only after all other backgrounded activities are released but before the foreground activity. A more complete description of process lifecycle rules around Services can be found in the Android docs here.
You may also want to look at the PowerManager and the use of PARTIAL_WAKE_LOCK, which would allow playback to continue when the handset would normally sleep (at the cost of battery life).