Adobe Flash AIR override Android back button - android

In my AIR AS3 app I'm trying to override Back Button like this:
NativeApplication.nativeApplication.addEventListener( KeyboardEvent.KEY_DOWN, onKey );
private function onKey(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK)
{
//stage.addChild(new MainMenuScreen());
//stage.removeChild(this);
//removeEventListener(KeyboardEvent.KEY_DOWN, onKey);
}
}
It seems to me that my code is getting done but the default Android behaviour (App is closed) is executed as well.
Have someone faced this problem?

If you want to stop the app closing, you should intercept the EXITING event:
NativeApplication.nativeApplication.addEventListener(Event.EXITING, exitHandler);
function exitHandler(event:Event):void
{
event.preventDefault();
}
I guess i should add that you can manually close the app with:
NativeApplication.nativeApplication.exit();

Just prevent the default action (closing the application) but make sure you still allow the application to close if there's nothing else to do (by using a readyToClose variable, for example):
private function onKey(e:KeyboardEvent):void
{
if(e.keyCode == Keyboard.BACK)
{
if(!readyToClose)
{
e.preventDefault();
//stage.addChild(new MainMenuScreen());
//stage.removeChild(this);
//removeEventListener(KeyboardEvent.KEY_DOWN, onKey);
}
}
}

Thank you all guys for your help!
The problem was due to my FlashDevelop IDE. I used PackageApp.bat instead of Run.bat, so wrong versions of my .apk were deployed onto device. Hope this post will help others who may face this problem

Here is another way to do it - if you use multiple stages you can put this in frame 1 of your first action panel
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, CheckKeypress, false, 0, true)
function CheckKeypress(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.BACK:
event.preventDefault();
gotoAndPlay (1);
break;
case Keyboard.MENU:
trace("Menu key is pressed.");
break;
case Keyboard.SEARCH:
trace("Search key is pressed.");
break;
}
}

Related

How to prevent on click event to fire twice

I'm trying to manage events in firetv app, the problem is on event fires Enter key and Click key at the same time, how can I prevent that?
Tried to use inEvent.stopImmediatePropagation(); but it still does not help.
$(document).on('click keydown', '.currentSlide', function (inEvent) {
var keycode;
var logger = $('#error-logger');
if(window.event) {
keycode = inEvent.keyCode;
} else if(e.which) {
keycode = inEvent.which;
} if (inEvent.type === 'click') {
keycode = 1;
}
console.log(`Keycode: ${keycode}`);
});
Clicking the remote button triggers the event twice and I'm trying to get it to only do it once.
Solved my problem by adding 1 more var that I set to true on keydown and on keyup to false again.
I'm not sure if there is better way of doing it but this will do for now.
Write the following as the first line in your function before you do anything
inEvent.stoppropagation()
this will stop any further events from triggering.

AS3: Air For Android - Using hardware back key to navigate to last used scene

I have been searching around to find a generic way to use the back key on android devices to go back to the previous scene you were on. All I seem to find is how to make it so the button does not close the application.
Here is my current code:
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true)
function onKeyDown(event:KeyboardEvent):void
{
if( event.keyCode == Keyboard.BACK )
{
event.preventDefault();
event.stopImmediatePropagation();
//handle the button press here.
}
}
Just tested it on my Android device, just change trace() with your function:
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPressed);
private function onKeyPressed(event:KeyboardEvent):void
{
if(event.keyCode == Keyboard.BACK)
{
event.preventDefault();
//Now you can call your function.
trace("Hello World");
}
}

How to identify back button event in Xamarin cross-platform (Xamarin.Forms)

Is there any way to know when the 'back' button event on the 'Android phone' is pressed? I'd like to exit the game and add few functionality to it when this button is pressed in Xamarin.Forms.
I googled a bit regarding this, but I got articles regarding Xamarin.Android Back button but not for Xamarin.Forms.
As I am relatively new to Xamarin.Forms, please help me out
public override void OnBackPressed()
{
//base.OnBackPressed();
}
Same thing I want in Xamarin.Forms. Need some assistance, guys.
If you mean Xamarin.Forms by "Xamarin Cross Platform", there is a OnBackButtonPressed event that you can use. As seen on that documentation:
Event that is raised when the hardware back button is pressed. This
event is not raised on iOS.
Simply override this event on your NavigationPage and you're ready to go:
protected override bool OnBackButtonPressed()
{
// Do your magic here
return true;
}
Good luck!
In my xamarin forms app you need to find the NavigationStack of the current Page if you are using master page:
public bool DoBack
{
get
{
MasterDetailPage mainPage = App.Current.MainPage as MasterDetailPage;
if (mainPage != null)
{
bool doBack = mainPage.Detail.Navigation.NavigationStack.Count > 1 || mainPage.IsPresented;
//top level of page and the Master menu isn't showing
if (!doBack)
{
// don't exit the app only show the Master menu page
mainPage.IsPresented = true;
return false;
}
else
{
return true;
}
}
return true;
}
}

menubutton not working anymore after upgrade to cordova 5+cordova android 4.0.0

I've recently upgraded to cordova 5 and removed/recreated android platform in version 4.0.0 and uninstalled/reinstalled all plugins.
I also had to upgrade android sdk to sdk 22 instead of 21.
Since the update, I'm no more able to catch the menubutton event as described in the cordova documentation.
As it's still referenced in the edge docs, I assume it should still be working and I've seen nothing about this in the release notes.
back button is still working.
I tried to set the target-sdk to 19, it did not solve anything about the issue.
Edit:
I've dug into cordova source code and found in CordovaWebViewImpl.java I found a suspicious TODO comment :
public void setButtonPlumbedToJs(int keyCode, boolean override) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_BACK:
// TODO: Why are search and menu buttons handled separately?
if (override) {
boundKeyCodes.add(keyCode);
} else {
boundKeyCodes.remove(keyCode);
}
return;
default:
throw new IllegalArgumentException("Unsupported keycode: " + keyCode);
}
}
Well my answer would be "IT SHOULDN'T!!!!"
Cordova makes a list of keycode to handle but does not add the menu button and later on the keycode is compared to KeyEvent.KEYCODE_MENU only after the keycode has been skipped because it's not in the list.
I've tried to add a case for the menu button, but it turns out the function is only called with the code of the back button.
So now I know why it doesn't work but still not how to fix it.
Edit 02/2016:
As per latest Jira, the support of the menubutton is now fixed in java part in Cordova Android 5.1.0 but still not initialized from the javascript.
For the moment, as indicated by Jira user Keith Wong, you need to add a javascript call before you add your event listener :
document.addEventListener("deviceready", function() {
...
navigator.app.overrideButton("menubutton", true); // <-- Add this line
document.addEventListener("menubutton", yourCallbackFunction, false);
...
}, false);
clarent's answer didn't do it for me, the menu button still didn't respond.
I tried several patches, one other suggestion to disable the boundKeyCodes check completely didn't do it either, because then the backbutton behaviour would be compromised.
The clean way to get the old behaviour back should be as follows.
The boundKeyCodes check ensures, that custom behaviour is only executed when there actually is a custom event handler bound to the event. But binding an event handler to "menubutton" in your app's JS code no longer triggers the menubutton key code to be added to the boundKeyCodes list.
This is because the setButtonPlumbedToJs method is never executed for the "menubutton" handler in the first place AND even if it would, the switch statement in this method doesn't handle KEYCODE_MENU.
You can get that behaviour back quite easily, first you will have to apply the change suggested by clarent:
Handle KEYCODE_MENU
in CordovaLib/src/org/apache/cordova/CoreAndroid.java (around line 357, setButtonPlumbedToJs) add a case statement after the KEYCODE_BACK entry like this:
public void setButtonPlumbedToJs(int keyCode, boolean override) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_MENU:
// TODO: Why are search and menu buttons handled separately?
if (override) {
boundKeyCodes.add(keyCode);
} else {
boundKeyCodes.remove(keyCode);
}
return;
default:
throw new IllegalArgumentException("Unsupported keycode: " + keyCode);
}
}
Then ensure that setButtonPlumbedToJs actually gets executed. You need two more changes for that.
Add framework handler
In CordovaLib/src/org/apache/cordova/CoreAndroid.java (around line 243, overrideButton) make the method look like this (add the last else-if clause):
public void overrideButton(String button, boolean override) {
if (button.equals("volumeup")) {
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_UP, override);
}
else if (button.equals("volumedown")) {
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_VOLUME_DOWN, override);
}
else if (button.equals("menubutton")) {
webView.setButtonPlumbedToJs(KeyEvent.KEYCODE_MENU, override);
}
}
Add javascript handler call
In platform_www/cordova.js (around line 1532, bootstrap) change this line:
cordova.addDocumentEventHandler('menubutton');
to this:
var menuButtonChannel = cordova.addDocumentEventHandler('menubutton');
menuButtonChannel.onHasSubscribersChange = function() {
exec(null, null, APP_PLUGIN_NAME, "overrideButton", ['menubutton', this.numHandlers == 1]);
};
This will trigger the frameworks overrideButton method as soon as an event handler is added to "menubutton".
That should do it. I also added this solution as a comment to
https://issues.apache.org/jira/browse/CB-8921
and might be filing a pull request shortly.
Just add to function setButtonPlumbedToJs one line : case KeyEvent.KEYCODE_MENU:
public void setButtonPlumbedToJs(int keyCode, boolean override) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_BACK:
case KeyEvent.KEYCODE_MENU:
So in onDispatchKeyEvent switch will work:
} else if (boundKeyCodes.contains(keyCode)) {
String eventName = null;
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
eventName = "volumedownbutton";
break;
case KeyEvent.KEYCODE_VOLUME_UP:
eventName = "volumeupbutton";
break;
case KeyEvent.KEYCODE_SEARCH:
eventName = "searchbutton";
break;
case KeyEvent.KEYCODE_MENU:
eventName = "menubutton";
break;
case KeyEvent.KEYCODE_BACK:
eventName = "backbutton";
break;
}
Now with cordova-android 5.1, the code has changed and my patch didn't work any-more (and sadly, with no patch the menu button is still not working in this version).
As I wanted to be able to upgrade the platform without having to review the code each time, I searched for a new way to get the menu button working again.
In cordova android 5.1 it turns out that everything is here in the java code for the button to be working, except that the menu button key is never added to the boundKeyCoded array.
It turns out that this array needs to be filled by a call from javascript (which is done for the back button and volume button, but neither for the search button or the menu button).
The code that is missing is something like that :
exec(null, null, APP_PLUGIN_NAME, 'overrideButton', ['menubutton' , true]);
(a js call to the java function overrideButton from CoreAndroid.java to tell to add the menu button key to the boundKeyCodes array.
I think this call should be added to platform.js, but since platform.js is used to build cordova.js during the platform add, I decided to make a after_platform_add hook that patchs the cordova.js file.
The advantage of this hook is that there's no java change and it should work even if you use a different webview like crosswalk.
So, first, in config.xml, in the android section add the hook :
<platform name="android">
....
....
<hook type="after_platform_add" src="scripts/android/patch_menubutton.js" />
....
....
</platform>
Then, in the scripts folder add the hook file patch_menubutton.js :
#!/usr/bin/env node
module.exports = function(ctx) {
var fs = ctx.requireCordovaModule('fs'),
path = ctx.requireCordovaModule('path');
var CordovaJSPath = path.join(ctx.opts.projectRoot, 'platforms/android/platform_www/cordova.js');
var data = fs.readFileSync(CordovaJSPath, 'utf8');
var result = data.replace(new RegExp("cordova\\.addDocumentEventHandler\\('menubutton'\\);", "g"), "cordova.addDocumentEventHandler('menubutton'); exec(null, null, APP_PLUGIN_NAME, 'overrideButton', ['menubutton' , true]);");
fs.writeFileSync(CordovaJSPath, result, 'utf8');
}
(it looks for the initialisation of the event handler for the menu button and appends the call to the overrideButton function, like described in the last part of FewKinG's answer)

AIR/as3 stage keylistener overriding input textfield

I'm building a mobile AIR app (Android & IOS) with Adobe Flash Builder 4.6 and I'm having this annoying problem.
Because I want to 'catch' the back-key on Android devices I added the following code to my main class:
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDown);
private function keyDown(k:KeyboardEvent):void {
if(k.keyCode == Keyboard.BACK) {
backClicked(); // function handling the back-action, not important
k.preventDefault();
}
Now somewhere else - nested in some classes - I've got a textfield:
TF = new TextField();
TF.type = TextFieldType.INPUT;
But when I set focus on the textfield the soft keyboard does appear, but I can't type a single character. When I disable the keylistener: no problem.
Seems like the listener is overriding my input field. Is there any workaround on this?
I have also implemented the back button functionality for my mobile apps , but i used to register keydown event only when my particular view is activated and removed the registered when view get deactivated.
in <s:view ....... viewActivate ="enableHardwareKeyListeners(event)" viewDeactivate="destroyHardwareKeyListeners(event)">
// add listener only for android device
if (Check for android device) {
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown, false, 0);
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp, false, 0);
this.setFocus();
}
private function destroyHardwareKeyListeners(event:ViewNavigatorEvent):void
{
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_DOWN))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_DOWN, handleHardwareKeysDown);
if (NativeApplication.nativeApplication.hasEventListener(KeyboardEvent.KEY_UP))
NativeApplication.nativeApplication.removeEventListener(KeyboardEvent.KEY_UP, handleHardwareKeysUp);
}
private function handleHardwareKeysDown(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK) {
e.preventDefault();
// your code
} else {
}
}
private function handleHardwareKeysUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.BACK)
e.preventDefault();
}
May this can help you.

Categories

Resources