Adobe AIR: Call JavaScript from a SWF (also win money)
The typical (and fairly safe) way to call a JavaScript function from a SWF is
ExternalInterface.call.
However, Adobe AIR does
NOT support ExternalInterface, so we have to look for an alternative if we want to interact with
embeded SWFs
in HTML AIR apps. Before ExternalInterface was introduced to ActionScript, there was
fscommand, navigateToURL, and getURL:
<!-- This goes in your Adobe AIR application -->
<object id="swf" type="application/x-shockwave-flash">
<param name="allowScriptAccess" value="sameDomain">
<param name="movie" value="myFlashFile.swf">
</object>
<script type="text/javascript">
// this function must be in "window" scope
function myFunc(str) {
air.trace("Flash told me: " + str);
}
</script>
<!--
NOTE: myFlashFile.swf contains this AS2 code...
getURL('javascript:myFunc("some argument");void(0);');
-->
Just like typing javascript: addresses into your browser's address bar, that example allows
Flash to call a JavaScript
function. HOWEVER...
Most likely for security reasons, getURL requires user interaction. You can call
getURL in an on(release) handler, but if you just want the SWF to call a JavaScript
function at an arbitrary point in the timeline, there must be user interaction. The user must actually be clicking
or moving the mouse on top of the SWF at the exact moment getURL is called, or the
call will fail silently.
What does this have to do with cash prizes? Well, at work I'm writing a touchscreen AIR app that loads SWF presentations. The user is just supposed to watch the movie, but the movie needs to call a function on my HTML page from time to time. Obviously, I can't ask the user to keep tapping the screen or constantly move their finger around the screen during the presentation, but I haven't found a clean way to allow Flash to call my JavaScript function without user interaction. We figured out a cheesy workaround, but I'm certain there must be a "real" way to accomplish this. So here are the requirements:
Demo Application and Contest Rules
This demo application reproduces the problem. Every four seconds, the
included SWF tries to call callMe(), a JavaScript function the app's HTML page. You can see that
while you move the mouse atop the SWF, the calls succeed, but as soon as you stop, so do the calls.
- Your SWF must call some JavaScript function defined in your AIR app's HTML page. Doesn't matter what it does, I just want to see a working example. Alert something, air.trace something, change colors, write text to a div, whatever you want.
- The function call must succeed with NO user interaction. No clicks, no mouse movement, no keypress.
- All source code must be available. For obvious reasons I won't run any submission I can't test by compiling the source.
- Your SWF can be written in either ActionScript 2 or 3, so long as you provide the source.
- No external applications (AutoIt, etc.).
- You can submit your solution in as many parts or files as you need, and any required installation or configuration process is fine as long as you can explain what to do.
I will send (via PayPal or personal check, whichever you prefer) $50 of my own hard earned cash to the first person to meet ALL of the above requirements. You get the cash whether the solution is an easy one-liner or a crazy convoluted workaround. No haggling, please — we already figured out a hack for work, so this contest is only for my own satisfaction. And hopefully yours if you like money.
To submit your solution, please post a link in the comments on this page. You can save the solution as text on PasteBin if you don't have your own hosting.
To embed a link in your comment here, use BBCode-style tags. For example, [url]http://your.web.site/path/file.ext[/url]







7 Comments
This contest isn't over, because if the docs say it doesn't work, I assume at some point it will STOP working. So if you have a different answer you can still win this.
Air_Javascript_Bridge.mxml
htmlwithJS.html
function calledFromAS() {
alert('Javascript alert from Actionscript');
}
Air_Javascript_Bridge.mxml
]]>
htmlwithJS.html
function calledFromAS() {
alert('Javascript alert from Actionscript');
}
]]>