My Game Keep Restarting Every Time I Lock/Unlock Screen In ICS/Jellybean

hi, not sure if i should post this in android section or here but considering not many replies there im sorry to bring the discussion here. Basically i have tested my game in two devices. One is still using Froyo 2.2 and another one is now using jellybean (4.1). Considering the very similar features of Jellybean and ICS, i believe this bug would also appear in ICS devices (hence the title of my thread)

so when I played the game i went idle for 1-2 minutes but after I unlocked the screen the app “auto restart” by itself. Im not sure why and what should I add in the codes to prevent this but I don’t see the same bug in Froyo.

Another question is, how do I add the “are you sure you want to quit?” confirmation box thingey for android whenever the user click the back button in his device? Because im sure this is a very common feature in android games but i never seen any sample codes here that teach us that feature. [import]uid: 114765 topic_id: 29037 reply_id: 329037[/import]

Brad,

The last release version of Corona, build 840, had a bug where the app would sometimes crash on an Android 4.0.3 or higher device after suspending or exiting the app. Perhaps this is what’s happening to you. We fixed this issue in build 849. I recommend that you trying testing this out with the newest daily build to see if it solves this problem. If it doesn’t, then would you mind posting a log of what happens when you resume your app after the screen lock please? You can access the Android log via “adb logcat” or “ddms”.

Regarding overriding the Back key, have a look at sample app “Hardware\KeyEvents” that is included with the Corona SDK on how to do this.

I hope this helps! [import]uid: 32256 topic_id: 29037 reply_id: 116948[/import]

hello there, thanks for the answer!

Yes finally i resolved the bug by downloading the latest daily build. Thank you for that :slight_smile:

as for the back key, yes im aware that the code to detect back button/key in android is there in your sample app but i dont know how and what to edit in order to add the “are you sure you want to quit?” box. I do know how to create such pop up box (once i read a part about that one) but where to add it in this case? This is what you have in your sample app:

[code]-- The Key Event Listener

local function onKeyEvent( event )
local returnValue = true

local phase = event.phase
local keyName = event.keyName
eventTxt.text = “(”…phase…" , " … keyName …")"
print( "Listener: " … event.name )

– Make an exception for Volume Up key and default to it’s normal function (just for show)
if “volumeUp” == keyName then
returnValue = false – use default key operation
print( “found ‘volumeUp’ key” )
end

– we handled the event, so return true.
– for default behavior, return false.
return returnValue
end

– Add the key callback
Runtime:addEventListener( “key”, onKeyEvent );[/code]

what to modify here?

and btw, im aware that you have this part in build.settings:

UIApplicationExitsOnSuspend = true,

i do need to add that line to my build.settings right? [import]uid: 114765 topic_id: 29037 reply_id: 116978[/import]

I don’t believe that Android uses anything inside the plist = {} table. I’m pretty sure that’s iOS only settings, so UIApplicationExitsOnSuspend would only control iOS devices.

As far as how to show a dialog to the player, there are several different methods.

If you are using Director 1.4, they support the idea of popup’s. Storyboard has a similar feature called Overlays. In both cases you have a separate Lua module that manages the display of the popup, just like you would any scene. Then when the player interacts with whatever controls you give them you can either close the popup or hide the overlay.

You of course could create your own screen by loading a background, adding buttons to it, to do what you want and then clean up when you’re done.

Though perhaps the simplest method is to use native.showAlert() to popup a native alert box and you can program multiple buttons, and then your app can respond to the user’s wishes when then alert closes. [import]uid: 19626 topic_id: 29037 reply_id: 116994[/import]

I recommend using the [lua]native.showAlert()[/lua] button. You can display when the Back key event is received, during the “down” phase. You can attach a Lua listener to that alert dialog which will receive which button the user has pressed. It’s pretty easy to set up.

Have a look at the documentation here…
http://docs.coronalabs.com/api/library/native/showAlert.html
[import]uid: 32256 topic_id: 29037 reply_id: 117042[/import]

hey there, thanks for the solution! It works! Sorry for my late reply (i wasnt working on this last weekend) but i encountered a new bug. OK so basically I have the “pause” function when the native.showAlert box pop up (so the game paused when there’s box “are you sure you want to quit” popping up). I have, of course, built a resume function in “cancel” button inside that pop up box.

HOWEVER, the issue is, if I click the back button twice (which will make the pop up box disappear) the game will still be paused. I don’t know where to build my resume function in order to resume the game if I touch the back button. Here’s what I have:

[code]local function onKeyEvent( event )
local returnValue = true

local phase = event.phase
local keyName = event.keyName

– Make an exception for Volume Up key and default to it’s normal function (just for show)
if “back” == keyName then
physics.pause()
paused = true
gameIsActive = false
monkeybaby:pause()

local function onComplete( event )
if “clicked” == event.action then
local i = event.index
if 1 == i then
os.exit()
elseif 2 == i then
physics.start()
paused = false
gameIsActive = true
monkeybaby:play(“rolling”)
end
end
end

– Show alert with two buttons
local alert = native.showAlert( “Corona”, “Test”, { “OK”, “Cancel” }, onComplete )
end

– we handled the event, so return true.
– for default behavior, return false.
end

– Add the key callback
Runtime:addEventListener( “key”, onKeyEvent );
return localGroup
end[/code]

check this part:

physics.start() paused = false gameIsActive = true monkeybaby:play("rolling")

this is basically my resume function which i implement in “cancel” button. How can I implement that function for touching the back button twice? [import]uid: 114765 topic_id: 29037 reply_id: 117553[/import]

The [lua]event.action[/lua] property can also be set to [lua]cancelled[/lua], which will happen when the user presses the Back key or if you call the [lua]native.cancelAlert()[/lua] function. Add support for that and you are good to go. [import]uid: 32256 topic_id: 29037 reply_id: 117587[/import]

hello there, thanks again. It works! unfortunately, once again, i found another bug! duh!

so basically i have a restart function at the top right of the game with this code

onSystemEvent () Runtime:removeEventListener("touch", stop ) Runtime:removeEventListener("enterFrame", wrapit) Runtime:removeEventListener("enterFrame", bananacheck) Runtime:removeEventListener("enterFrame", chkCollisions) Runtime:removeEventListener("system", onSystemEvent ) audio.stop (gameMusicChannel) director:changeScene("game")

as you can see in above code i remove every event listener there as tutored few months ago by someone else here. The code of course works flawlessly until I implement the native.systemAlert feature here…

*PS: game.lua is the same file where I play the game - so yeah it is for restarting the game

now with the native.systemAlert pop up box, this function doesnt work 100% anymore. Yeah it restarts the game.lua but then after it gets restarted, I simply can’t touch the back button anymore (means, nothing happen if I click the back button after restarting). So if i restart the game and I click the back button the native.systemAlert pop up box simply wont show up and the app can’t quit as well. Why is this happening and what’s the solution to this? [import]uid: 114765 topic_id: 29037 reply_id: 117684[/import]

It sounds like your KeyEvent listener is still stealing the Back key and preventing your app from exiting. Is that what you are talking about?

The idea is that your KeyEvent listener function should return true if your app is overriding the key, thus preventing the app from exiting when the Back key is pressed… or return false if you do not want to override the key and allow the app to do the default handling.

Now, if you want your popup alert to exit the app when the user selects Yes/Okay, then you can call function [lua]native.requestExit()[/lua] to have your app exit. Is that what you want?
(Note that [lua]native.requestExit()[/lua] is only supported on Android. Apple does not allow/approve of apps that exit themselves.) [import]uid: 32256 topic_id: 29037 reply_id: 117781[/import]

hi there, i think you dont fully understand my issue.

I do understand about what native.systemAlert does (overriding the back key). My point is not that, my point is I do have a restart function located at the top right of the screen with the codes I mentioned earlier (stopping all event listeners). If let’s say I do restart my game by touching that function, the game will restart BUT THIS TIME the back key won’t function at all.

It means after I restart the game, the back key simply won’t do anything. It doesn’t quit the app nor showing up the systemAlert pop up box.

For better explanation, I will explain it like this:

  1. If i dont use your native.systemAlert at all, whenever I press the back button, it’ll quit the game, right?

  2. Now because I use your native.systemAlert code, whenever I press the back button, it’ll show up the pop up box instead of quitting the app directly.

  3. But if I press the restart button I built earlier, then I press the back button after the game restarted, it simply won’t do anything. Means it won’t quit the app nor showing up anything. The back button is simply not working at all (it doesn’t do anything if you press it after the game restarted).

I dont know what the problem is, i thought i forgot to remove event listener for onKeyEvent in my restart function but apparently it doesn’t solve the problem.

Thanks! [import]uid: 114765 topic_id: 29037 reply_id: 117827[/import]

bump, i need help for this final problem! thx! [import]uid: 114765 topic_id: 29037 reply_id: 117856[/import]

It sounds like your KeyEvent listener is still overriding the Back key after you reset your game. You can prove it by adding a [lua]print()[/lua] statement to your [lua]onKeyEvent()[/lua] function and watch the Android log when you press the back key. That’s my best suggestion to help you debug it.

Remember that your [lua]onKeyEvent()[/lua] function needs to return false if you do NOT want to override the back key and you want Android to do the default back key handling… which is to exit out of the app. That’s the problem. Your code isn’t doing that. Add print statements to your function and verify that your code is doing what you intended it to do. [import]uid: 32256 topic_id: 29037 reply_id: 117916[/import]

Sir Joshua, thank you so much for your reply. I have tried my best to find a solution for this but couldnt find it. I have added return false but it doesnt solve it. Every time a restart function or changeScene is used (let’s say I don’t changeScene back to game.lua after stopping all event listeners, instead i changeScene back to main.lua) it will always cause the back key to stop functioning at all like I mentioned in my previous post. Basically I use changeScene function from director.lua to change scene/restart the same scene. Do you believe director could be the cause?

as for debugging, I believe it’s impossible to do. I know we only need to add print () and use debugger if we want to debug something but I can’t debug the back key function. If you try to click the back key in corona simulator you will see that it’s not functioning there. Im using corona latest daily build (the one i downloaded last week i guess) and it’s still not functioning. i mean how can I debug the back key if I simply can’t click the back key in corona simulator?

*PS: I have added eventTxt.text = "("..phase.." , " .. keyName ..")" in order to show up every key for debugging purpose but still I couldnt find my onkeyevent one in debugging mode. When the error occurs, whenever i hit “back” button it will not show anything in the text above, but if i hit other buttons such as volume or search button it will print out the button keyname. I suspect it never goes to onKeyEvent(event) function if the problem occurs. [import]uid: 114765 topic_id: 29037 reply_id: 118038[/import]

The KeyEvent listener will only work on an actual Android device and never in the Corona Simulator. What I meant was that you can view a real-time log from your Android device if you connect it to your computer via USB and run the “adb logcat” command line tool that is included with the Android SDK from Google. Your print() functions will output to that log and is really useful for debugging.

I would put a print() function at the top of your [lua]onKeyEvent()[/lua] function and a print statement just before the [lua]return false[/lua] to verify that your Lua listener is getting called and it is returning false when expected. I’m guessing that your code is supposed to remove the KeyEvent listener when your done with it, and I’m guessing that it’s not being removed and is still overriding the back key. Nothing else in the Corona code will block the back key on our end. So I have no other explanation.

Another thing to look into is to never remove the KeyEvent listener and instead use variables to tell it whether or not it is okay for it to leave the app or not. Much simpler in my opinion. [import]uid: 32256 topic_id: 29037 reply_id: 118072[/import]

Hi,

Thx for your reply and suggestion to debug with ADB. Finally i can narrow down the problem.

Actually here is the root cause:

  1. I put onKeyEvent() in my game.lua to override the “back” button function. I override the “back” button to do some pause mechanism and show local alert = native.showAlert( "Corona", "Test", { "OK", "Cancel" }, onComplete ). If I press “OK” button, screen will change to menu.lua using director class.
  2. Then I press “back” button again in menu.lua but it will still trying to call onKeyEvent() which i specified in game.lua previously.

Why is the behavior like this? Or am I wrong if i put the onKeyEvent() inside game.lua?
[import]uid: 114765 topic_id: 29037 reply_id: 118827[/import]

Your [lua]onKeyEvent()[/lua] function will continue to receive events until you remove it’s event listener as follows…
[lua]Runtime:removeEventListener(“key”, onKeyEvent)[/lua]

I did not see you remove this event listener in the code that you’ve posted up above. So, perhaps you have forgotten to do this?

Although, in my opinion, you may want to keep the onKeyEvent listener in your main.lua and have it listen for keys at all times. This is to avoid a quirk (not a bug) that some people run into where if they remove a key event listener as they leave a scene via the Back key and then they immediately add a key event listener for the next scene, that new listener will receive that same Back key event. This is because Corona’s event dispatcher is still in the middle of going through its list of listeners sending key events and that new scene just pushed itself to the end of that list, therefore receiving that same key event. Setting up a single key event listener in your main.lua and handling it yourself for all scenes from there is a much simpler method of handling it. [import]uid: 32256 topic_id: 29037 reply_id: 118915[/import]

im sorry sir but that doesnt work either. Removing event listener for onKeyEvent doesnt solve the problem. I dont know why but it just doesnt do it (actually i have added the code since 2 weeks ago before debugging, just that i forgot to edit my previous post here. and yes i can confirm again right now that it doesnt help).

I think the problem is not because of the back key event but the changeScene feature itself. As you know yourself, i use director.lua for changing scene and using director always needs to remove every event listener Runtime:removeEventListener

and im having this thought that this kind of “complicated” feature is actually the one that caused the mess. Do you know any simpler way to change scene from game.lua to main.lua (or vice versa) without needing to remove event listeners AND AT THE SAME TIME still make the game work flawlessly? Maybe that’s the culprit? Because there’s no way to override/remove event listener for the back key when we change scene using director.

Basically using director to change scene and try to remove event listener for the back key after changing scene won’t solve the bug.

and pardon me but im not sure what do you mean by this statement:

[text]Setting up a single key event listener in your main.lua and handling it yourself for all scenes from there is a much simpler method of handling it.[/text]

how do i set up single key event listener in main.lua and handle it for all scenes from there? [import]uid: 114765 topic_id: 29037 reply_id: 119520[/import]

You can set up a single key event handler as shown below. The trick here is to give that one key event listener a reference to the function that will handle the event via variable [lua]keyEventHandler[/lua]. Remember that Lua is a functional language and allows you to store a function into a variable as shown below.

[lua]local keyEventHandler = nil
local function keyEventListener(event)
if keyEventHandler then
keyEventHandler(event)
end
end

local function pageOneKeyEventHandler(event)
– Handle key event here…
– Use page 2’s key event handler.
keyEventHandler = pageTwoKeyEventHandler
end

local function pageTwoKeyEventHandler(event)
– Handle key event here…
– Use page 1’s key event handler.
keyEventHandler = pageOneKeyEventHandler
end

keyEventHandler = pageOneKeyEventHandler
Runtime:addEventListener(“key”, keyEventListener)[/lua]

You may have to massage the above code to work best for you, but this is my best advise. [import]uid: 32256 topic_id: 29037 reply_id: 119545[/import]

im sorry sir but that doesnt work either. Removing event listener for onKeyEvent doesnt solve the problem. I dont know why but it just doesnt do it (actually i have added the code since 2 weeks ago before debugging, just that i forgot to edit my previous post here. and yes i can confirm again right now that it doesnt help).

I think the problem is not because of the back key event but the changeScene feature itself. As you know yourself, i use director.lua for changing scene and using director always needs to remove every event listener Runtime:removeEventListener

and im having this thought that this kind of “complicated” feature is actually the one that caused the mess. Do you know any simpler way to change scene from game.lua to main.lua (or vice versa) without needing to remove event listeners AND AT THE SAME TIME still make the game work flawlessly? Maybe that’s the culprit? Because there’s no way to override/remove event listener for the back key when we change scene using director.

Basically using director to change scene and try to remove event listener for the back key after changing scene won’t solve the bug.

and pardon me but im not sure what do you mean by this statement:

[text]Setting up a single key event listener in your main.lua and handling it yourself for all scenes from there is a much simpler method of handling it.[/text]

how do i set up single key event listener in main.lua and handle it for all scenes from there? [import]uid: 114765 topic_id: 29037 reply_id: 119520[/import]

You can set up a single key event handler as shown below. The trick here is to give that one key event listener a reference to the function that will handle the event via variable [lua]keyEventHandler[/lua]. Remember that Lua is a functional language and allows you to store a function into a variable as shown below.

[lua]local keyEventHandler = nil
local function keyEventListener(event)
if keyEventHandler then
keyEventHandler(event)
end
end

local function pageOneKeyEventHandler(event)
– Handle key event here…
– Use page 2’s key event handler.
keyEventHandler = pageTwoKeyEventHandler
end

local function pageTwoKeyEventHandler(event)
– Handle key event here…
– Use page 1’s key event handler.
keyEventHandler = pageOneKeyEventHandler
end

keyEventHandler = pageOneKeyEventHandler
Runtime:addEventListener(“key”, keyEventListener)[/lua]

You may have to massage the above code to work best for you, but this is my best advise. [import]uid: 32256 topic_id: 29037 reply_id: 119545[/import]