Back button not working on android?

I’m trying to consume the back button and do something based on it’s press. I simplified it to simply this 
 

function onKeyEvent(event) return true end Runtime:addEventListener("key", onKeyEvent)

In theory this should just consume any button presses and do nothing right? Well it works with corona sdk but doesn’t work with corona cards. Just wondering if this is a known bug? I see from other forum posts that the key event is supported so just wondering what the issue might be. 

dmglakewood - from one of our engineers:


Returning true for a key event in Corona prevents the operating system from handling the key event.  In effect, you’re telling the operating system that your app is handling the key.  So, returning true for *all* key events like he is doing will prevent the operating system from handling all keys such as Back, VolumeUp, VolumeDown, etc.  (except for the Home key which apps never receive).

 

You should only return true for the back key when he wants to block the app from being closed.  We provide an example here…

   http://docs.coronalabs.com/daily/api/event/key/keyName.html


Right I get that, but returning true on just the back button wasn’t working so I decided to return true on all keys just to see if it would work. The code I posted should work like so I think

User opens the app > presses the back button > nothing happens

That’s how it should work but in my app it’s like so

User opens the app > presses the back button > app closes 

My actual code is a lot more complex then the one I posted but I was trying it as simple as possible just to make sure it wasn’t my code that was causing the issue. 
 

I’m also using corona inside a fragment not sure if that’s the issue?

After playing around for a while I realized that sometimes (very very rarely) it works as it should. If I’m playing the game, turn off the screen and then back on and the first thing I do is hit the back button every now and then it will sometimes run the lua code but like 95% of the time it just ignores that code for some reason. 

The Android version of CoronaCards doesn’t support key events.  Only Corona Enterprise and Corona Simulator built apps support key events.  Sorry about the confusion.

So, your only option is to handle key events on the Java side using Google’s Android APIs via the Activity.onKeyDown() and/or Activty.onKeyUp() methods.

   [http://developer.android.com/reference/android/app/Activity.html#onKeyDown(int](http://developer.android.com/reference/android/app/Activity.html#onKeyDown(int), android.view.KeyEvent)

   [http://developer.android.com/reference/android/app/Activity.html#onKeyUp(int](http://developer.android.com/reference/android/app/Activity.html#onKeyUp(int), android.view.KeyEvent)

Okay cool that’s no problem I just wanted to confirm that it’s not supported before I spent the time building it in java. Although now that I think about it, all I have to do is use the same function I already had and just send an event from java to lua and call that function. It’s so simple I’m almost upset I didn’t think about doing that sooner.

Great.  One gotcha you’ll need to watch out for is that Java key events will be received on the main UI thread, but Corona/Lua runs on the OpenGL thread.  So, you can’t make direct function calls from your Java key event listeners to your Lua code.  Probably the best solution to this problem is to have your Lua script dispatch a CoronaView event to your Java listener indicating whether or not the back key event should be overridden or not.

In case you haven’t already seen it, we document how to communicate between Lua and Java here…

  http://docs.coronalabs.com/daily/coronacards/android/communication.html

Okay that confused me a little bit. So I can easily pass to java if I should override the button press, but would I then send an even back to lua? It’s not that I just want to enable or disable the back button I’m trying to overrried it so I can close a scene without closing my app. If I just override it in java that will prevent it from closing but no event will fire on the lua side correct? 

Edit: Okay so what I did was setup a lua to java listener and a java to lua listener. When I exit the home scene I send an event to java telling it to override the back button, when on the home scene I send java an event telling it to not override the back button. If the back button is overriden and it gets pressed I then send an event to lua telling it that the back button was pressed. Seems to be working like a charm. It wasn’t as simple as I was thinking but it really wasn’t that hard either.

Here is my code for anyone that is looking to override the back button 

Java code

//This boolean should go just after you create your activity (outside of the fragment) private boolean overrideBackButton = false; //This block of code should be inside your fragment //Lua to Java listener mBigCoronaView.setCoronaEventListener(new CoronaEventListener() { @Override public Object onReceivedCoronaEvent(CoronaView view, Hashtable\<Object, Object\> event) { final String eventName = (String) event.get("eventName"); if(eventName.equals("backButtonOverride")){ overrideBackButton = (Boolean) event.get("value"); } return ""; } }); //This override should also be outside of your fragment @Override public void onBackPressed() { //See if we should override back button if(overrideBackButton){ //Send back button event to lua Hashtable\<Object, Object\> event = new Hashtable\<Object, Object\>(); event.put("name", "backButton"); mBigCoronaView.sendEvent(event); return; } super.onBackPressed(); }

Lua Code

--//When you want to override the back button send this event Runtime:dispatchEvent({ name = "coronaView", eventName = "backButtonOverride", value = true }) --//When you don't want to override the back button (back button will close the app) send this event Runtime:dispatchEvent({ name = "coronaView", eventName = "backButtonOverride", value = false }) --//This should go in your main.lua --//This function handles what to do when the back button is pressed local function handleBackButton(event) print("Back button overriden") end Runtime:addEventListener("backButton", handleBackButton)

You should have complete control over your back button now. What I did so I didn’t have to use a ton of events was place the true event on exit of my main lobby scene. If the user exits that scene then it means they are in a secondary scene and I want to override the back button so when pressed they will to back to the main scene. On the show of the main scene I set the value to false and the back button will close the app. That way I only have to write 2 events in my whole app. 

Thanks for Sharing this!

Rob

dmglakewood - from one of our engineers:


Returning true for a key event in Corona prevents the operating system from handling the key event.  In effect, you’re telling the operating system that your app is handling the key.  So, returning true for *all* key events like he is doing will prevent the operating system from handling all keys such as Back, VolumeUp, VolumeDown, etc.  (except for the Home key which apps never receive).

 

You should only return true for the back key when he wants to block the app from being closed.  We provide an example here…

   http://docs.coronalabs.com/daily/api/event/key/keyName.html


Right I get that, but returning true on just the back button wasn’t working so I decided to return true on all keys just to see if it would work. The code I posted should work like so I think

User opens the app > presses the back button > nothing happens

That’s how it should work but in my app it’s like so

User opens the app > presses the back button > app closes 

My actual code is a lot more complex then the one I posted but I was trying it as simple as possible just to make sure it wasn’t my code that was causing the issue. 
 

I’m also using corona inside a fragment not sure if that’s the issue?

After playing around for a while I realized that sometimes (very very rarely) it works as it should. If I’m playing the game, turn off the screen and then back on and the first thing I do is hit the back button every now and then it will sometimes run the lua code but like 95% of the time it just ignores that code for some reason. 

The Android version of CoronaCards doesn’t support key events.  Only Corona Enterprise and Corona Simulator built apps support key events.  Sorry about the confusion.

So, your only option is to handle key events on the Java side using Google’s Android APIs via the Activity.onKeyDown() and/or Activty.onKeyUp() methods.

   [http://developer.android.com/reference/android/app/Activity.html#onKeyDown(int](http://developer.android.com/reference/android/app/Activity.html#onKeyDown(int), android.view.KeyEvent)

   [http://developer.android.com/reference/android/app/Activity.html#onKeyUp(int](http://developer.android.com/reference/android/app/Activity.html#onKeyUp(int), android.view.KeyEvent)

Okay cool that’s no problem I just wanted to confirm that it’s not supported before I spent the time building it in java. Although now that I think about it, all I have to do is use the same function I already had and just send an event from java to lua and call that function. It’s so simple I’m almost upset I didn’t think about doing that sooner.

Great.  One gotcha you’ll need to watch out for is that Java key events will be received on the main UI thread, but Corona/Lua runs on the OpenGL thread.  So, you can’t make direct function calls from your Java key event listeners to your Lua code.  Probably the best solution to this problem is to have your Lua script dispatch a CoronaView event to your Java listener indicating whether or not the back key event should be overridden or not.

In case you haven’t already seen it, we document how to communicate between Lua and Java here…

  http://docs.coronalabs.com/daily/coronacards/android/communication.html

Okay that confused me a little bit. So I can easily pass to java if I should override the button press, but would I then send an even back to lua? It’s not that I just want to enable or disable the back button I’m trying to overrried it so I can close a scene without closing my app. If I just override it in java that will prevent it from closing but no event will fire on the lua side correct? 

Edit: Okay so what I did was setup a lua to java listener and a java to lua listener. When I exit the home scene I send an event to java telling it to override the back button, when on the home scene I send java an event telling it to not override the back button. If the back button is overriden and it gets pressed I then send an event to lua telling it that the back button was pressed. Seems to be working like a charm. It wasn’t as simple as I was thinking but it really wasn’t that hard either.

Here is my code for anyone that is looking to override the back button 

Java code

//This boolean should go just after you create your activity (outside of the fragment) private boolean overrideBackButton = false; //This block of code should be inside your fragment //Lua to Java listener mBigCoronaView.setCoronaEventListener(new CoronaEventListener() { @Override public Object onReceivedCoronaEvent(CoronaView view, Hashtable\<Object, Object\> event) { final String eventName = (String) event.get("eventName"); if(eventName.equals("backButtonOverride")){ overrideBackButton = (Boolean) event.get("value"); } return ""; } }); //This override should also be outside of your fragment @Override public void onBackPressed() { //See if we should override back button if(overrideBackButton){ //Send back button event to lua Hashtable\<Object, Object\> event = new Hashtable\<Object, Object\>(); event.put("name", "backButton"); mBigCoronaView.sendEvent(event); return; } super.onBackPressed(); }

Lua Code

--//When you want to override the back button send this event Runtime:dispatchEvent({ name = "coronaView", eventName = "backButtonOverride", value = true }) --//When you don't want to override the back button (back button will close the app) send this event Runtime:dispatchEvent({ name = "coronaView", eventName = "backButtonOverride", value = false }) --//This should go in your main.lua --//This function handles what to do when the back button is pressed local function handleBackButton(event) print("Back button overriden") end Runtime:addEventListener("backButton", handleBackButton)

You should have complete control over your back button now. What I did so I didn’t have to use a ton of events was place the true event on exit of my main lobby scene. If the user exits that scene then it means they are in a secondary scene and I want to override the back button so when pressed they will to back to the main scene. On the show of the main scene I set the value to false and the back button will close the app. That way I only have to write 2 events in my whole app.