Posts in Category "AIR"

Front-facing Camera Support in AIR 3

Adobe AIR for mobile has had consistent camera support since AIR 2.6, and now in AIR 3 (in beta, available on Adobe Labs), we’ve introduced support for front-facing cameras, as well. The introduction of the new position property on Camera along with the constants in the new CameraPosition class (BACK, FRONT, and UNKNOWN) allow you to chose which camera you want to get a reference to before attaching it to a Video object.

To be honest, the API is not quite as elegant as I’d like because making it consistent across platforms (mobile and desktop) meant having to compromise a little intuitiveness, but it’s easy enough to figure out, and most importantly, it’s entirely cross-platform. The code below shows a simple function that will return the requested camera:

// Get the requested camera. If it cannot be found,
// return the device's default camera instead.
private function getCamera(position:String):Camera
  for (var i:uint = 0; i < Camera.names.length; ++i)
    var cam:Camera = Camera.getCamera(String(i));
    if (cam.position == position) return cam;
  return Camera.getCamera();

For a full working example, check out the demo application called FrontCameraExample on Github (you can also download the FXP file). Keep in mind that AIR 3 is still in beta, so you might find bugs. If you do, here’s how to file them.

How to File Adobe AIR Bugs

I just wanted to post a quick reminder that we now have a public bug base for Adobe AIR. You can find it at, and it currently supports both AIR and Flash Player (along with a few other products).

In case you’re not accustomed to filing bugs, it’s hugely important to be as thorough and precise as possible. The absolute best way to file a bug is to provide a simple use case (with code) that reproduces the issue along with detailed instructions on how to run it. The first step in fixing a bug is being able to reliably reproduce it.

The bugs entered through the public bug base go directly into our internal bug tracking system and our review queue, so the better the bug report, the faster it gets in front of an engineer to start being looking at. To anyone who has taken the time to file a bug, we really appreciate your contribution!

How to Use the AIR 3 Beta SDK

The AIR 3 runtime has been out in beta for some time, and now the AIR 3 SDK is available, as well. If you’re interested in checking it out, you can find it over on Adobe Labs.

If you’ve downloaded the SDK and want to give it a try, you’ll need to know how to set it up. There are really only two things you need to know:

  1. How to overlay the SDK. Although these instructions are a little old, I just reviewed them, and they’re still valid. Of course, SDK versions are different now, but in general, the instructions are still accurate.
  2. How to access the new AIR 3 APIs. Once you have the AIR 3 SDK properly overlaid, you’ll need to make one simple change in Flash Builder in order to be able to access the new APIs. Once you’ve created a new project and selected the correct SDK (the one you just created), you need to go to "Project Properties," then "Flex Compiler." In the "Additional compiler arguments" box, add "-swf-version=13". 13 is the SWF version that corresponds to AIR 3, so you need to tell the runtime what version of the APIs you want to use.

That’s about all you need to do to get started building AIR 3 (beta) applications.

When AIR Applications Prevent Shutdown or Restart on Mac OS X

Update (7/27/2011): I just added another partial solution at the end of this post.

My friend Ben Simon occasionally uses AIR when he has clients who need cross-platform desktop applications. Recently, Ben discovered that an AIR application he’s working on is preventing OS X from shutting down or restarting. Specifically, when the application is running, choosing "Restart…" or "Shut Down…" from the Apple menu results is the OS claiming that the AIR application canceled the restart.

I started looking into the issue for him, and the first thing I discovered is that this definitely doesn’t happen with all AIR applications. I was able to narrow the issue down pretty quickly to just applications that stay running even though all their windows are closed. Further investigation led me to discover that the issue has to do with calling event.preventDefault() on the closing event thrown by NativeWindow (one technique for having applications "minimize" to the system tray on Windows or the Dock on Mac is stop the main application window from closing and hiding it, instead).

From what I can tell, there are two pretty solid ways to work around this issue:

  1. Use custom chrome. If you draw your own window chrome, rather than listening for the CLOSING event and calling event.preventDefault(), you can just listen for the click event on the close button in the window chrome and set the visible property on the window to false right there.
  2. If you really want or need to use system chrome, the best work-around I’ve come up with so far is to move your main application into a separate component that extends NativeWindow (let’s call it Main.mxml). That way, you can set the visible property of your main application window to false, then just open and close new instances of Main.mxml as you need to (as opposed to toggling the visible property).

There are probably other ways to get this to work, but unfortunately I’ve run out of time to test them right now. If you have your own techniques, feel free to post them in the comments.

Update (7/27/2011): A partial solution occurred to me this morning. If you check to see if your window is visible before calling preventDefault(), your application won’t stop the OS shutdown in cases where all your application windows are already closed. The following code will do the trick:

private function onWindowClosing(e:Event):void
    if (this.visible)
        this.visible = false;

The reason this is only a partial solution is that it only stops preventDefault() from being called when the window isn’t visible, but if your application has visible windows, preventDefault() will still be called which will still cancel the OS shutdown or restart. Better than nothing, but still not perfect.

Tooling for Adobe AIR 2.6

Since we launched AIR 2.6, I’ve seen a lot of questions online about tooling support, so I thought I’d try to clear some things up.

We frequently release the AIR runtime and SDK in advance of releasing new versions of tools (Flash Builder and Flash Professional) for two reasons:

  1. The tools need some additional time to catch up to the SDK. In other words, the tools are downstream of the SDK, so after we’ve added all our features, the Flash Builder and Flash Professional teams need time to add and test support for those features.
  2. Although we could hold off on releasing the SDK until the tools were ready, we figure it’s better to put the runtime and the SDK into developers’ hands as early as possible since, even without tooling support, it is still possible to develop with them (primarily from the command line).

The next versions of Flash Builder and Flash Professional will support AIR 2.6, and will be out the first half of this year. In the meantime, I would encourage Flash Builder users to join the private pre-release program which gives you access to a build of Flash Builder which has support for AIR 2.6. There is currently no pre-release program offered for Flash Professional, although Flash Professional users can still use the AIR 2.6 SDK from the command line.

Although it’s not officially supported, Flash Builder users can also use either Flash Builder 4 or Flash Builder “Burrito” to build AIR 2.6 applications, but with two caveats:

  1. The mobile workflow in Burrito doesn’t work with the 2.6 SDK. You can build 2.6 applications (desktop or mobile), but Burrito won’t automatically deploy them to a device. You will need to use the 2.5 SDK to get device integration, or deploy your application to your device manually (I use the adb tool that comes with the Android SDK).
  2. If you use Flash Builder 4 for AIR 2.6 development, make sure to read the post How to Use AIR 2.6 with Flash Builder 4. (The quick answer is to add the -target-player=11 flag to the compiler arguments.)

We know it’s not ideal to release a new runtime and SDK without also releasing tooling support at the same time, but we feel like getting a new version of AIR out there early is worth the tradeoffs.

Owned Windows in AIR 2.6

One of the new desktop features in AIR 2.6 is owned windows. Owned windows are primarily designed for when you want a utility or a lightweight window to be related to another window as in the case of a tool pallet. The following describes the relationship between owned windows and their owners:

  • Owned windows always have a higher z-order than their owners which means they always appear on top (you wouldn’t want a tool pallet to get lost behind your application window).
  • When you minimize or hide the owner, all owned windows are minimized, as well. When you restore the owner, the owned windows are also restored.
  • When you close the owner, all owned windows also close.

Here’s an example of owned windows in action:

And here’s the code:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="" xmlns:s="library://" xmlns:mx="library://">
            private function openNewWindow(owned:Boolean):void
                var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
                initOptions.type = NativeWindowType.UTILITY;
                if (owned) initOptions.owner = this.nativeWindow;
                var newWin:NativeWindow = new NativeWindow(initOptions);
                newWin.title = (owned) ? "Owned Window" : "Normal Window";
    <s:VGroup width="100%" height="100%" verticalAlign="middle" horizontalAlign="center">
        <s:Button label="Open Ownded Window" click="openNewWindow(true);"/>
        <s:Button label="Open Regular Window" click="openNewWindow(false);"/>

Native Cursors in AIR 2.6

One of the coolest new desktop features in AIR 2.6 is the ability to use native cursors. By "native cursor," I mean custom cursors at the OS level as opposed to the runtime level. In other words, rather than hiding the mouse cursor and rendering a sprite in its place (the old way to do custom cursors which doesn’t always perform well), in AIR 2.6, you can hand one or more bitmaps to the operating system along with a frame rate and a hot spot, and the cursor will be rendered (and optionally animated) in hardware.

Here’s an example:

Here’s everything you need to know about custom cursors in AIR 2.6:

  • The data property of MouseCursorData takes a vector of BitmapData objects so you can create an animation. Use the frameRate property to control the animation’s frame rate.
  • You can control which part of the cursor is the "hot spot" (the portion that registers clicks) using the hotSpot property of MouseCursorData.
  • When the cursor leaves the application’s native window, your custom cursor will revert to the default OS cursor.
  • The maximum cursor size is 32×32.

Full docs are available here.

And here’s the code. (I used the Smurf sprite sheet from here, though I put them all on a single row and scaled them down to 32×32 to simplify the code.)

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.ui.Mouse;
    import flash.ui.MouseCursorData;

    public class NativeCursorExample extends Sprite
        [Embed(source="smurf.png")] private var SmurfClass:Class;

        private static const SMURF_WIDTH:uint  = 32;
        private static const SMURF_HEIGHT:uint = 32;

        private var SMURF_CURSOR_NAME:String = "smurf";

        public function NativeCursorExample()
            var bitmaps:Vector.<BitmapData> = new Vector.<BitmapData>;

            var spriteSheet:Bitmap = new SmurfClass();

            var r:Rectangle;
            var bmd:BitmapData;
            var p:Point = new Point(0, 0);

            for (var i:uint = 0; i < 16; ++i)
                r = new Rectangle((SMURF_WIDTH * i) , 0, SMURF_WIDTH, SMURF_HEIGHT); 
                bmd = new BitmapData(r.width, r.height, true, 0x000000);
                bmd.copyPixels(spriteSheet.bitmapData, r, p);
            var mcd:MouseCursorData = new MouseCursorData();
   = bitmaps;
            mcd.hotSpot = new Point(22, 15); // The smurf's nose
            mcd.frameRate = 24;
            Mouse.registerCursor(SMURF_CURSOR_NAME, mcd);
            Mouse.cursor = SMURF_CURSOR_NAME;

How to Use AIR 2.6 with Flash Builder 4

Flash Builder 4 and AIR 2.6 are technically not a supported configuration, and the version of Flash Builder Burrito that is on Labs is not 2.6 compatible yet, either. Fortunately, with a very simple work-around, it is possible to combine AIR 2.6 and Flash Builder 4.

The first thing you need to do is overlay the SDK (combine the AIR SDK with the Flex SDK). These instructions haven’t been updated in some time, but they’re still accurate.

Once you’ve added the new SDK in Flash Builder, you will find that you have access to new AIR 2.6 APIs (overview here), however if you try to run your application, you will get a runtime VerifyError. To work around this issue, follow these simple steps:

  1. Right-click on your project and choose "Properties".
  2. Select the "Flex Compiler" section.
  3. In the "Additional compiler arguments" field, add -target-player=11.
  4. Click "OK".

Debug your application again, and everything should work fine.

AIR 2.6 Applications and the Amazon Appstore for Android

Update (4/15/2011): The first URL I posted has been deprecated. The new URL is now below.

With the upcoming launch of the Amazon Appstore for Android, AIR developers are wondering if they can take advantage of this new distribution channel. Starting with AIR 2.6, the answer is yes!

The key to making your AIR applications compatible with the Amazon Appstore for Android is overriding the runtime download URI. The runtime download URI specifies the location from which the runtime will be downloaded if it’s not already installed. The default URI points to the runtime in Google’s Android Market, but starting with AIR 2.6, that URI can be overridden.

The version of ADT in the 2.6 AIR SDK supports the new airDownloadURL command line option when packaging your APK file. To make your AIR 2.6 application compatible with the Amazon Appstore for Android, your ADT command should look something like this:

adt -package -target ( apk | apk-debug | apk-emulator ) ( CONNECT_OPTIONS? | -listen <port>? ) ( -airDownloadURL )? SIGNING_OPTIONS <output-package> ( <app-desc> PLATFORM-SDK-OPTION? FILE-OPTIONS | <input-package> PLATFORM-SDK-OPTION? )

When building an APK for the Amazon Appstore for Android, there are three things to be aware of:

  1. Android applications built with Adobe AIR 2.5 (the first version to support Android) won’t work with the Amazon Appstore for Android because the runtime download URI points to Google’s Android Market. You have to repackage your application with the AIR 2.6 SDK using the airDownloadURL flag to make it compatible.
  2. You will need to build two separate APK files — one for Google’s Android Market, and one for the Amazon Appstore for Android. Although you will have to manage the process of building two separate APK files, your application’s code doesn’t have to change at all. The only difference is the packaging process.
  3. The Amazon Appstore for Android does not support filtering on processor type. Adobe AIR for Android requires an ARMv7-A processor which means users who have both Android 2.2 or higher (the minimum Android version AIR requires), and an ARMv6 processor, can still download AIR applications even though they won’t work. Amazon and Adobe are working together to get this issue resolved as soon as possible.

Everything New in Adobe AIR 2.6

Adobe AIR 2.6 is now live (runtime and SDK). The primary focus of 2.6 is to achieve feature parity between Android and iOS, however we did manage to sneak some good features in for the SDK, Android, and for the desktop profile, as well.

Here’s a list of everything that’s new in AIR 2.6.

  • Asynchronous Bitmap Decoding. This features allows bitmaps to optionally be decoded in another thread as opposed to on-demand in the main thread. Setting the imageDecodingPolicy property on a LoaderContext to ImageDecodingPolicy.ON_LOAD enables asynchronous bitmap decoding which can keep your application more responsive and make animations much smoother.
  • Owned Windows. The use case for owned windows is primarily things like tool palettes. The owned window feature allows you to associate one NativeWindow with another so that the owned window is always above its owner in z-order. This was probably mostly possible before owned windows using things like activate events and the orderInBackOf, orderInFrontOf, orderToBack, and orderToFront APIs, but with owned windows, all you have to do is pass the owner of the new window in with the NativeWindowInitOptions object, and everything is handled for you. Much easier.
  • Bitmap Capture in StageWebView. The new drawViewPortToBitmapData function on StageWebView lets you draw the view port of a StageWebView to a bitmap. This feature has two primary use cases. The first and most obvious is the ability to grab a "screen capture" of the StageWebView, and the second (related) use case has to do with positioning Flash content on top of a StageWebView. Since it’s not possible to position Flash content on top of a StageWebView (Flash content is always drawn below), taking a snapshot of the content lets developers swap the StageWebView out for a bitmap when you need to position Flash content on top of it, then swap the StageWebView back when you’re ready.
  • Microphone support on iOS. The Microphone APIs now work on iOS.
  • StageWebView¬†on iOS. Just like on Android, the StageWebView now works on iOS.
  • Multitasking on iOS. With 2.6, AIR applications will get activate and deactivate events on iOS as users switch to and from the app. AIR applications will also be properly resumed rather than restarted (unless the OS has decided to kill it for some reason which both iOS and Android reserve the right to do for any application).
  • Retina Support on iOS. Pretty self-explanatory. 2.6 has support for the very high-resolution iPhone 4 and iPod touch screens (326 PPI), and the higher resolution application icons.
  • iOS Camera, CameraUI, and CameraRoll Support. The Camera and CameraUI APIs are now supported on iOS, just like on Android. (Be sure to read How to Use CameraUI in a Cross-platform Way if you going to use these APIs for apps that you want to run on both iOS and Android devices).
  • Improved hardware acceleration on iOS. Hardware acceleration on iOS now works like it does on Android, and generally provides much better performance than with PFI. And speaking of PFI…
  • PFI is now ADT. The PFI (Packager for iPhone) utility is gone, and its functionality has been integrated into ADT. ADT can now be used to package AIR files, native desktop installers, Android applications, and iOS apps. I should also mention that iOS applications (IPA files) can be built and copied to iOS devices on Windows using ADT and iTunes. Very slick.
  • Configurable panning with soft keyboard activation. When a text field receives focus in an AIR application on a mobile device, the soft keyboard is generally shown, and if the keyboard covers the text field, the UI is automatically panned so that the text field isn’t obscured. This behavior is now configurable. By default, nothing will change, but starting with 2.6, developers can use an application descriptor setting to override the default behavior. With <softKeyboardBehavior> set to none in the application descriptor, the UI will not automatically pan. Rather than using the default behavior, developers can listen for the softKeyboardActivating event on the Stage and use the softKeyboardRect property to modify their applications’ layout themselves.
  • Programmatic control of the display of the on-screen keyboard. Using the new requestSoftKeyboard() function on InteractiveObject, along with the needsSoftKeyboard and softKeyboardInputAreaOfInterest properties, developers can now have complete programmatic control over displaying the soft keyboard. (Note that these APIs are Android-only and not supported on iOS.)
  • Support for the Amazon Android Market. AIR applications built with the AIR 2.6 SDK can be distributed on the new Amazin Appstore for Android. See my post AIR 2.6 Applications and the Amazon Appstore for Android for details.
  • Vector printing on Linux. If you can get your printer to work on Linux, you can now get vector printing in AIR. (Personally, I have terrible luck with printers on any OS.)
  • Native cursor support. This is a big one. If you’ve ever changed the cursor in Flash or Flex, you know there are several disadvantages like a noticeable performance hit, pauses in animated cursors due to CPU usage, and the fact that the custom cursor only works inside the AIR application (what’s really happening is that the native mouse cursor is being hidden, and a sprite is being rendered in its place which has to listen for MouseMove events to follow the invisible cursor). With AIR 2.6, developers have access to real native cursors. The new MouseCursorData class takes one or more bitmaps and a hotSpot Point, and creates an actual native cursor.
  • On-device debugging over USB (Android only). No more wrestling with WiFi debugging. Mobile Android apps can now be debugged over USB.
  • Native Menu event refinement. This one is subtle, but important. Sometimes an application needs to dynamically prepare a NativeMenu before showing it in order to add, remove, or disable items. That’s what the Event.DISPLAYING event is for. But a NativeMenu can be used without it actually being displayed as in the case of key equivalents being associated with NativeMenuItems. If a user is interacting with a NativeMenu using the keyboard, no displaying event is thrown which means that the code never has the opportunity to dynamically change the menu. That’s what the new Event.PREPARING event is for. A preparing event is thrown before a NativeMenu is displayed, and before it is accessed with a keyboard shortcut, making it somewhat more generic than a displaying event. I would recommend using Event.PREPARING from now on in case you ever decide to add keyboard shortcuts to your menus.
  • Enhanced text support on Android. Another big one. AIR 2.6 has support for scrolling, text selection, and text context menus (for cut/copy/paste) on Android.
  • NetConnection.httpIdleTimeout. In AIR 2, we added the URLRequest.idleTimeout and URLRequestDefaults.idleTimeout properties. In AIR 2.6, we’re adding similar support to NetConnection with the new httpIdleTimeout property.
  • Bundled Android USB drivers on Windows. Mac users can just connect their Android devices and start copying files and/or debugging right away. Windows users need to install Android USB drivers first. The AIR 2.6 SDK will have Windows USB drivers for most Android devices bundled to make this process much easier.
  • Support for the vipaccess:// URI. The vipaccess:// URI for invoking VeriSign’s VIP Access application is now white-listed in AIR.
  • -version flag for ADT. Running ADT with the -version flag will now return the version of ADT.