system event applicationResume and applicationSuspend bug [FIXED]

Hello

I created a hook to capture system events.  I wanted to be able to detect application suspend and resume to handle my apps memory.

Runtime:addEventListener( "system", onSystemEvent );

My onSystemEvent looks like this

local function onSystemEvent( event ) DoPrint("System Event: " .. event.type .. " (Previous Event: " .. tostring(previousEvent) .. ")") if "applicationExit" == event.type then local soundChannel = audio.play( cachedSoundAppExit, { channel=3} ) -- Create the unique file before exiting createExitFile() elseif "applicationOpen" == event.type then local soundChannel = audio.play( cachedSoundAppOpenInterchange, { channel=3} ) -- http://coronalabs.com/blog/2011/12/22/using-app-url-schemes-in-ios/ native.showAlert( "Open via custom url", event.url, { "OK" } ) elseif "applicationSuspend" == event.type then -- todo save state, drop mem? local soundChannel = audio.play( cachedSoundAppSuspending, { channel=3} ) elseif "applicationResume" == event.type then --local alert = native.showAlert( "applicationResume", event.response, { "OK" } , onGenericAlertBox()) local soundChannel = audio.play( cachedSoundAppResume, { channel=3} ) GetOpenWeatherMapData() elseif "applicationStart" == event.type then local soundChannel = audio.play( cachedSoundAppStart, { channel=3} ) -- check to see if file exist if isExitFile() then DoPrint (" Last Application Run, Safe Exit Detected (Found SafeExit.flg)") end else local alert = native.showAlert( "Unknown System Event Type", tostring(event.type), { "OK" }, onGenericAlertBox() ) end return true end

Bugs:

  1. applicationResume never gets fired.

  2. applicationSuspend gets fired when the app resumes on the simulator and devices.

I am using build v2014.2205 on a mid 2012 Mac Book Pro Retina 15" OSX 10.9.2 and an iPhone 5 with iOS 7.1.

Config

settings = { orientation = { default = "portrait", supported = { "landscapeLeft", "landscapeRight", "portrait", "portraitUpsideDown" }, }, iphone = { plist = { UIApplicationExitsOnSuspend = false, etc...

Can you try without the return true at the end?

Yep, same result

No event is fired when the app suspends and when the app resumes it fires the suspend event.

I added print statements and the suspend is not triggered on suspend but is triggered on resume event??

local function onSystemEvent( event ) DoPrint("System Event: " .. event.type .. " (Previous Event: " .. tostring(previousEvent) .. ")") if "applicationExit" == event.type then DoPrint(" Processed systemEvent:applicationExit()") local soundChannel = audio.play( cachedSoundAppExit, { channel=3} ) createExitFile() -- Create the unique file before exiting elseif "applicationOpen" == event.type then DoPrint(" Processed systemEvent:applicationOpen()") local soundChannel = audio.play( cachedSoundAppOpenInterchange, { channel=3} ) -- http://coronalabs.com/blog/2011/12/22/using-app-url-schemes-in-ios/ native.showAlert( "Open via custom url", event.url, { "OK" } ) elseif "applicationSuspend" == event.type then DoPrint(" Processed systemEvent:applicationSuspend()") -- todo save state, drop mem? local soundChannel = audio.play( cachedSoundAppSuspending, { channel=3} ) elseif "applicationResume" == event.type then DoPrint(" Processed systemEvent:applicationResume()") -- todo reload assets local soundChannel = audio.play( cachedSoundAppResume, { channel=3} ) elseif "applicationStart" == event.type then DoPrint(" Processed systemEvent:applicationStart()") local soundChannel = audio.play( cachedSoundAppStart, { channel=3} ) -- check to see if file exist if isExitFile() then DoPrint (" Last Application Run, Safe Exit Detected (Found SafeExit.flg)") end -- else -- local alert = native.showAlert( "Unknown System Event Type", tostring(event.type), { "OK" }, onGenericAlertBox() ) end -- return true end

Fixed

It appears you can’t play audio when an app is suspending, any calls to play audio are paused until the app resumes, when the app resumes the resume audio retries to play but the suspend audio is already in the pipeline.

I changed the code to

  1. don’t play sounds on suspend

  2. search for a free channel before playing audio

Code:

 DoPrint("System Event: " .. event.type .. " (Previous Event: " .. tostring(previousEvent) .. ")") local availableChannel = audio.findFreeChannel() if "applicationExit" == event.type then DoPrint(" Processed systemEvent:applicationExit()") audio.play( cachedSoundAppExit, { channel=availableChannel} ) createExitFile() -- Create the unique file before exiting elseif "applicationOpen" == event.type then DoPrint(" Processed systemEvent:applicationOpen()") audio.play( cachedSoundAppOpenInterchange, { channel=availableChannel} ) -- http://coronalabs.com/blog/2011/12/22/using-app-url-schemes-in-ios/ native.showAlert( "Open via custom url", event.url, { "OK" } ) elseif "applicationSuspend" == event.type then DoPrint(" Processed systemEvent:applicationSuspend()") -- todo save state, drop mem? elseif "applicationResume" == event.type then DoPrint(" Processed systemEvent:applicationResume()") -- todo reload assets audio.play( cachedSoundAppResume, { channel=availableChannel} ) elseif "applicationStart" == event.type then DoPrint(" Processed systemEvent:applicationStart()") audio.play( cachedSoundAppStart, { channel=availableChannel} ) -- check to see if file exist if isExitFile() then DoPrint (" Last Application Run, Safe Exit Detected (Found SafeExit.flg)") end -- else -- local alert = native.showAlert( "Unknown System Event Type", tostring(event.type), { "OK" }, onGenericAlertBox() ) end -- return true end

Great to hear that you discovered this solution. It appears that you just identified a Gotcha that should be documented in the API pages. Thanks much for sharing. 

PS. I had a thread earlier on looking into this topic. I will link to your thread there as I think this is great learning for all. 

:slight_smile:

Can you try without the return true at the end?

Yep, same result

No event is fired when the app suspends and when the app resumes it fires the suspend event.

I added print statements and the suspend is not triggered on suspend but is triggered on resume event??

local function onSystemEvent( event ) DoPrint("System Event: " .. event.type .. " (Previous Event: " .. tostring(previousEvent) .. ")") if "applicationExit" == event.type then DoPrint(" Processed systemEvent:applicationExit()") local soundChannel = audio.play( cachedSoundAppExit, { channel=3} ) createExitFile() -- Create the unique file before exiting elseif "applicationOpen" == event.type then DoPrint(" Processed systemEvent:applicationOpen()") local soundChannel = audio.play( cachedSoundAppOpenInterchange, { channel=3} ) -- http://coronalabs.com/blog/2011/12/22/using-app-url-schemes-in-ios/ native.showAlert( "Open via custom url", event.url, { "OK" } ) elseif "applicationSuspend" == event.type then DoPrint(" Processed systemEvent:applicationSuspend()") -- todo save state, drop mem? local soundChannel = audio.play( cachedSoundAppSuspending, { channel=3} ) elseif "applicationResume" == event.type then DoPrint(" Processed systemEvent:applicationResume()") -- todo reload assets local soundChannel = audio.play( cachedSoundAppResume, { channel=3} ) elseif "applicationStart" == event.type then DoPrint(" Processed systemEvent:applicationStart()") local soundChannel = audio.play( cachedSoundAppStart, { channel=3} ) -- check to see if file exist if isExitFile() then DoPrint (" Last Application Run, Safe Exit Detected (Found SafeExit.flg)") end -- else -- local alert = native.showAlert( "Unknown System Event Type", tostring(event.type), { "OK" }, onGenericAlertBox() ) end -- return true end

Fixed

It appears you can’t play audio when an app is suspending, any calls to play audio are paused until the app resumes, when the app resumes the resume audio retries to play but the suspend audio is already in the pipeline.

I changed the code to

  1. don’t play sounds on suspend

  2. search for a free channel before playing audio

Code:

 DoPrint("System Event: " .. event.type .. " (Previous Event: " .. tostring(previousEvent) .. ")") local availableChannel = audio.findFreeChannel() if "applicationExit" == event.type then DoPrint(" Processed systemEvent:applicationExit()") audio.play( cachedSoundAppExit, { channel=availableChannel} ) createExitFile() -- Create the unique file before exiting elseif "applicationOpen" == event.type then DoPrint(" Processed systemEvent:applicationOpen()") audio.play( cachedSoundAppOpenInterchange, { channel=availableChannel} ) -- http://coronalabs.com/blog/2011/12/22/using-app-url-schemes-in-ios/ native.showAlert( "Open via custom url", event.url, { "OK" } ) elseif "applicationSuspend" == event.type then DoPrint(" Processed systemEvent:applicationSuspend()") -- todo save state, drop mem? elseif "applicationResume" == event.type then DoPrint(" Processed systemEvent:applicationResume()") -- todo reload assets audio.play( cachedSoundAppResume, { channel=availableChannel} ) elseif "applicationStart" == event.type then DoPrint(" Processed systemEvent:applicationStart()") audio.play( cachedSoundAppStart, { channel=availableChannel} ) -- check to see if file exist if isExitFile() then DoPrint (" Last Application Run, Safe Exit Detected (Found SafeExit.flg)") end -- else -- local alert = native.showAlert( "Unknown System Event Type", tostring(event.type), { "OK" }, onGenericAlertBox() ) end -- return true end

Great to hear that you discovered this solution. It appears that you just identified a Gotcha that should be documented in the API pages. Thanks much for sharing. 

PS. I had a thread earlier on looking into this topic. I will link to your thread there as I think this is great learning for all. 

:slight_smile: