Playing a sound while app is in the foreground and the screen is locked - iOS
Asked Answered
I

2

19

Preface: I'm building an alarm clock app. Many other alarm apps such as Alarm Clock Pro are able to play an alarm while the screen is locked and the app is in the foreground. Their alarms can play for an unlimited amount of time and can progressively increase in volume using the system volume. They also do not take control of the music controls (if you open up the multitasking screen and scroll to playing audio, you will not see their icon)

I am having some trouble reproducing that functionality.

To play alarms while the app is in the foreground we fire Local notifications which works great. I've have some limited success while the screen is locked (the and the app is in the Inactive state)

I've used the following methods:

  1. Run an NSTimer every second with a background task when the screen is locked. I managed to keep the app open past the 10 minute maximum but I was unable to play a sound. when the time came

  2. Play a 1 second silent sound using AVAudioPlayer. When the sound ends, replay the sound and check if the app is in the Inactive (locked screen) state. If it is in the locked screen state and it's time to play an alarm, play it. The problem here is I must use

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

in order to continue updating the song while it's in the background. That method will display Wake in the music controls and will stop any currently playing music which we want to avoid.

  1. A combination of #1 and #2. When the app opens play a silent sound on infinite repeat. When the screen is locked fire a timer to check if its time to play an alarm. When it's time to play an alarm, switch the silent sound to the alarm sound. The system would eventually force close the app

Related knowledge that has helped but hasn't solved my question:

  1. How do I start playing audio when in silent mode & locked in iOS 6?
  2. iOS 5 deep sleep prevention
  3. Resuming execution of code after interruption while app is in background
  4. How to play music in background iphone sdk

Summary: While the screen is locked and in the app is in the foreground, I am unable to prevent the process from being killed off after the 10 minute mark.

UPDATE

I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer which let me play a sound after 10 minutes. However, this eats up battery like crazy. I need to find a more efficient solution.

UPDATE 2

I downloaded some of http://marcopeluso.com/ apps from the app store. He is the creator of the Deep Sleep Preventer. I downloaded some of his apps and ran some instruments tests and saw his app was not draining battery as much as my app is (roughly 2.5% per hour as claimed somewhere on his blog). I am very certain that I need to optimize my app and the battery drain problems will disappear and my problems will be solved!

UPDATE 3 I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer

I ran it in it's own separate xCode project and it only uses 0.5% of the cpu when the app is in the background. It turns out it was my app was sucking the cpu. So all it working well now :)

Instructive answered 12/3, 2013 at 15:3 Comment(4)
To try to summarize your problem, is it that you can get this to work, but only for up to 10 minutes after the screen locks?Authenticate
Added a bold summary at the bottom, hope it helpsInstructive
I know that your app is in the foreground but you may try to solve your problem with "background music" and "background tasks". A tutorial can be found here: mobile.tutsplus.com/tutorials/iphone/ios-sdk_background-audio I assume that the foreground process is halted after 10 minutes to save battery.Bethina
That did not work but this did github.com/mruegenberg/MMPDeepSleepPreventer However! it is draining the battery pretty heavily. I need to find a more efficient way to do thisInstructive
I
1

See my response above. Basically though

I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer

I ran it in it's own separate xCode project and it only uses 0.5% of the cpu when the app is in the background. It turns out it was my code that was killing the cpu. All is well now!

Instructive answered 31/3, 2013 at 18:8 Comment(6)
How much battery drain were you seeing? I'm losing around 20% of my battery overnight using MMPDeepSleepPreventer - not sure if this is normal or not. What did you end up doing to get your app to stop draining the battery?Chelsiechelsy
That sounds about right. It's not the best solution but the only working one I could find. I modified MMPDeepSleepPreventer to play a sound less often, I believe once every 9 minutes because the app has 10 minutes of background life. This may save some battery life but I doubt it.Instructive
@Instructive Hi gabe.roze, I have same problem and tried to use MMPDeepSleepPreventer class but problem is that how to differentiate home button pressed or power button pressed. Because as you described above these apps working only when power button is pressed but not when home button is pressed. I also want same behaviour of app. Can you help me please?Ithyphallic
My app does not run in the background as with most alarms. In the info.plist I have Application does not run in background set to YES. When the home button is pressed, my app is killed and MMPDeepSleepPreventer does nothing. When the lock button is pressed, MMPDeepSleepPreventer is enabled. I call MMPDeepSleepPreventer in the AppDelegate under applicationWillResignActive and [deepSleepPreventer stopPreventSleep] in applicationDidBecomeActive I also init MMPDeepSleepPreventer in didFinishLaunchingWithOptionsInstructive
Hi @gabe.roze, from MMPDeepSleepPreventer, they said that it might get rejected from the app store due to playing non audible sound, is your app on the store ?? did you have to resubmit your app ?? did you face any problems ?? iOs 7 or whatever... I'm stuck, but not sure if I can use MMPDeepSleepPreventer :SZechariah
@Nour1991 yeah, it is only a viable option when the app is in the foreground and the screen is locked. We got rejected when we tried to keep the app alive while not in the foreground.Instructive
A
1

Even if your app is in the foreground when the device is on, after it's locked it will go to background (willresignactive is called). Now from what I gathered around the internet you should not be looping the sound yourself but instead provide the custom music file in one of these formats in your main app bundle:

  • Linear PCM
  • MA4 (IMA/ADPCM)
  • µLaw
  • aLaw

The custom sound can only be 30 seconds or less. After initializing your UILocalNotification object you need to set its firedate property, which is date and time (also recurring) for firing the notification. Then you set the alert message through alertBody (like "wake up") and the string on the alert button through alertAction. The file name of the custom sound goes into the soundName property. You present your notification instance by calling scheduleLocalNotification:, a UIApplication method. Note that the time you call this method does not need to be, and usually is not, the time when the notification will fire.And you only need to call this once even if you set a recurring notification.You cancel it by calling cancelLocalNotification: . Now your alarm should play whether your app is in foreground, background or not even open.

It's all in here.

Anis answered 13/3, 2013 at 20:1 Comment(3)
Hey, thanks for your reply but this is not an ideal solution for what I am doing. If you have used any of the good alarm clock apps, when the screen is locked and their app is in the foreground, an alarm will play regardless of your systems set volume and silence setting. There is a plausible solution using local notifications and repeats but they will not provide for a great user experience as the user has to ensure that the app is not silenced before going to bed, rendering the app useless as an alarm.Instructive
I hope you can find a reliable way for your app not to get killed while the device is locked. But even then, as an alarm clock user, I would not want to have to remember to open your app (every time I switch off and on the device) because otherwise the alarm won't play..Anis
Ended up finding a solution. I'm fairly certain that there are plenty alarms on the app store that use this now. See my comment above.Instructive
I
1

See my response above. Basically though

I ended up using https://github.com/mruegenberg/MMPDeepSleepPreventer

I ran it in it's own separate xCode project and it only uses 0.5% of the cpu when the app is in the background. It turns out it was my code that was killing the cpu. All is well now!

Instructive answered 31/3, 2013 at 18:8 Comment(6)
How much battery drain were you seeing? I'm losing around 20% of my battery overnight using MMPDeepSleepPreventer - not sure if this is normal or not. What did you end up doing to get your app to stop draining the battery?Chelsiechelsy
That sounds about right. It's not the best solution but the only working one I could find. I modified MMPDeepSleepPreventer to play a sound less often, I believe once every 9 minutes because the app has 10 minutes of background life. This may save some battery life but I doubt it.Instructive
@Instructive Hi gabe.roze, I have same problem and tried to use MMPDeepSleepPreventer class but problem is that how to differentiate home button pressed or power button pressed. Because as you described above these apps working only when power button is pressed but not when home button is pressed. I also want same behaviour of app. Can you help me please?Ithyphallic
My app does not run in the background as with most alarms. In the info.plist I have Application does not run in background set to YES. When the home button is pressed, my app is killed and MMPDeepSleepPreventer does nothing. When the lock button is pressed, MMPDeepSleepPreventer is enabled. I call MMPDeepSleepPreventer in the AppDelegate under applicationWillResignActive and [deepSleepPreventer stopPreventSleep] in applicationDidBecomeActive I also init MMPDeepSleepPreventer in didFinishLaunchingWithOptionsInstructive
Hi @gabe.roze, from MMPDeepSleepPreventer, they said that it might get rejected from the app store due to playing non audible sound, is your app on the store ?? did you have to resubmit your app ?? did you face any problems ?? iOs 7 or whatever... I'm stuck, but not sure if I can use MMPDeepSleepPreventer :SZechariah
@Nour1991 yeah, it is only a viable option when the app is in the foreground and the screen is locked. We got rejected when we tried to keep the app alive while not in the foreground.Instructive

© 2022 - 2024 — McMap. All rights reserved.