AIR 3.0 Captive Runtime

If you hadn’t heard yet, Beta 2 of AIR 3.0 and Flash Player 11 are now availabe on Adobe Labs. The AIR 3.0 beta release is sporting some great new features, including hardware accelerated video playback for mobile, iOS background audio, android licensing support, front-facing camera support, encrypted local storage for mobile, H.264 software encoding for desktop applications, and last, but not least, captive runtime support for desktop and Android applications.

If you are wondering what “captive runtime support” is, then I’ll try to explain… Currently all AIR applications that are deployed on the desktop and in Android require the 3rd-party Adobe AIR runtime. If you are familiar with the process for developing mobile AIR applications for Apple’s iOS devices, then you may already know that these applications don’t require the 3rd-party runtime; they are completely self-contained applications. These AIR applications for iOS already take advantage of the captive runtime. All necessary components of the AIR framework are bundled into a self-contained, compiled distributable application that has no dependence upon other frameworks.

With AIR 3.0, you will have the option to bundle the AIR framework into your applications to eliminate the 3rd-party dependency. However, one thing to keep in mind is that you can only export mac application packages on Macs and Windows EXEs on Windows. You can’t target native installers or bundled runtimes for cross-platform development. You can only have a single app that targets both platforms if you export a .AIR file (which requires the 3rd-party AIR runtime).

Instructions for using the captive runtime:
First, make sure that you extract the AIR runtime SDK from the archive. Instructions for extracting the AIR SDK are located at: http://kb2.adobe.com/cps/495/cpsid_49532.html

Next, add a compiler argument for swf-version=13.

Then use the ADT command line utility to build and package your application. If you run the ADT tool on the command line without passing any arguments, it will show you all of the packaging options.

For the Android captive runtime, you just need to select the target “apk-captive-runtime“, as identified by:
[bash]adt -package -target ( apk | apk-debug | apk-emulator | apk-captive-runtime ) ( CONNECT_OPTIONS? | -listen <port>? ) ( -airDownloadURL <url> )? SIGNING_OPTIONS <output-package> ( <app-desc> PLATFORM-SDK-OPTION? FILE-OPTIONS | <input-package> PLATFORM-SDK-OPTION? )[/bash]

For the desktop captive runtime, you need to select the target “bundle“, as identified by:
[bash]adt -package SIGNING_OPTIONS? -target bundle SIGNING_OPTIONS? <output-package> ( <app-desc> FILE-OPTIONS | <input-package> )[/bash]

Mobile (3G) vs. WIFI Network Detection with Adobe AIR

Did you know that you can determine whether your mobile device is on wifi or your mobile data connection when using Adobe AIR for mobile? To be honest, I wasn’t aware of it either until yesterday when my friend and former colleague Brian O’Connor pointed me towards a recent tweet from @adobe_cookbook that showed an example how to do it.

These networking APIs have been around since AIR 2.0, but I’ve seldom had the need to dig into them for the desktop. Now that AIR for mobile is widely available, this can be critically important for your applications. For example, what if you want to minimize network usage while on the mobile network? This may even prevent you being chastised for eating up expensive mobile bandwidth.

Using the NetworkInfo class’ findInterfaces() method, you can retrieve a list of all network interfaces on your computer/device. If you iterate through these, you can see which are active, what their IP and MAC addresses are, and even which IP protocol version they are using. Here’s a quick example (code below the video):

Network Detection on AIR Mobile

I know that video is a little hard to see, so here are some screen captures. First, a capture showing the mobile network connection active:

Mobile Network Active

Next, a capture showing the WIFI network active:

WIFI Network Active

Basically, I just have a list that shows all of the network interfaces. When the app loads, or whenever the network connection changes, the content of that list is updated to reflect the current state of the network interfaces. If you want to determine whether you are on wifi, you can compare the name of the active network interface to see if it contains the string “wifi”, as shown in the Adobe Cookbook.

[as3]<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
title="Network Detection"
creationComplete="view1_creationCompleteHandler(event)">

<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;

[Bindable]
private var interfaces : ArrayCollection = new ArrayCollection();

protected function view1_creationCompleteHandler(event:FlexEvent):void
{
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetworkChange);
updateInterfaceDataProvider();
}

protected function onNetworkChange(event : Event) : void
{
updateInterfaceDataProvider();
}

//this is used b/c you can’t bind directly to a Vector
protected function updateInterfaceDataProvider() : void
{
interfaces.disableAutoUpdate();
interfaces.removeAll();

for each ( var ni : NetworkInterface in NetworkInfo.networkInfo.findInterfaces() )
{
interfaces.addItem( ni );
}
interfaces.enableAutoUpdate();
}
]]>
</fx:Script>

<s:List dataProvider="{ interfaces }"
width="100%" height="100%"
itemRenderer="NetworkInterfaceDetailsRenderer"/>
</s:View>[/as3]

In the list renderer, I’m simply setting an iconFunction and messageFunction to reflect the details on each individual NetworkInterface.

[as3]<?xml version="1.0" encoding="utf-8"?>
<s:IconItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
labelField="name"
messageFunction="networkInterfaceDetail"
iconFunction="networkInterfaceIcon"
iconWidth="64" iconHeight="64" >

<fx:Script>
<![CDATA[

[Embed(source="assets/active.png")]
public static var activeImageClass:Class;

[Embed(source="assets/inactive.png")]
public static var inactiveImageClass:Class;

private function networkInterfaceDetail(item:Object):String
{
var ni : NetworkInterface = this.data as NetworkInterface;
if ( ni )
{
var result : String = "mac: " + ni.hardwareAddress;
for each ( var ia : InterfaceAddress in ni.addresses )
{
result += "\nip: " + ia.address + " " + ia.ipVersion;
}
result += "\nmtu: " + ni.mtu.toString();
return result;
}

return "Error: Unable to identify network interface.";
}

private function networkInterfaceIcon(item:Object):Object
{
var ni : NetworkInterface = this.data as NetworkInterface;
if ( ni && ni.active )
return activeImageClass;
return inactiveImageClass;
}
]]>
</fx:Script>
</s:IconItemRenderer>
[/as3]

One thing not to forget: You must make sure that your application has been provisioned to allow access to network interfaces! You’ll just need to uncomment the Android permissions in your app.xml for network state:

[xml]
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>[/xml]

Molehill (Stage3D) on Mobile

I recently had the opportunity to start playing around with Molehill for mobile (hardware accelerated 3D graphics), and I think it is something that many of you will be very excited about (see video below). Everyone thinks that 3D is just for games, but it’s not… 3D graphics can be used for complex data visualizations, scientific modeling, or a whole host of other subject areas.

I started down the path of creating 3D charts that are capable of rendering on mobile, using the Away3D engine. This is really just exploratory work, and I have it rendering multiple axes with 250 spheres (individual data points), which is about 70K-90K polygons drawn onscreen at any given time. Check out the preview below:

Molehill (Stage3D) on Mobile

This preview is running on a Motorola Atrix, and Samsung Galaxy Tab 10.1 with a prerelease AIR runtime… more devices will coming soon. Source code will be available once molehill for mobile has been released.

Molehill (Stage3D) on Mobile recorded via iPhone

You can see another preview of molehill for mobile here: http://www.bytearray.org/?p=3053

Enjoy!

Making ColdFusion/Flash Remoting and WordPress Play Nice on IIS

OK, this post isn’t completely about Flash, Flex, or Mobile, but it is about ColdFusion, so I guess it’s still applicable…  I recently made a few changes my WordPress blog (specifically adding “pretty” permalinks for posts).   In order for this to work properly, you have to add rewrite rules in your web.config so that IIS will be able to map URLs to wordpress/PHP, where it can correctly resolve the URL to the actual post.   (You can read more about WP permalinks here.)

Once you setup the rewrite rules, all is well and good, right?  Well, almost… This is an IIS server, running ColfFusion and PHP.   While the wordpress blog was working great, I realized that all of my AMF remoting on the server stopped working.  It turns out that the rewrite rules were affecting all pages that don’t physically exist.  This includes the “/Flex2Gateway/” endpoint used by ColdFusion to resolve all AMF requests.  Note: the “Flex2Gateway” url path doesn’t point to a physical folder or file; it is a virtual mapping.

In order for WordPress and ColdFusion to play nicely together on the same server, you will need to setup your rewrite rules to map all URLs that don’t contain the string “flex2gateway”.   It’s not that complicated really, but took a little while to track down what exactly was happening.  I used the ECMAScript pattern syntax for a regular expression that will match all strings that don’t include “flex2gateway”, and here’s the final solution:

[xml]
<rule name="wordpress" patternSyntax="ECMAScript">
<match url="^((?!flex2gateway).)*$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
[/xml]

Adobe Releases Beta of Edge HTML5 Tool

Exciting news this morning!  I awoke to see that Adobe has released a beta version of EDGE, the HTML5 motion and interaction Design tool on Adobe Labs, as well as theexpressiveweb.com/, an HTML5 showcase site.

EDGE will allow you to create Flash-like timeline animations purely using standards-compliant HTML.  You can see a preview form the examples site below:

EDGE Sample (note: may not work in every browser)

You can read a bit more about theexpressiveweb.com and the thoughts behind it on Adobe devnet at: http://www.adobe.com/devnet/html5/articles/introducing-expressive-web.html

theexpressiveweb.com