Setting Custom Labels on Lists with the PlayBook

By default, it seems like the only property that the QNX List class can display as a label is label. In Flex I was used to being able to set my own label property or my own custom label function but it doesn’t look like that’s possible in the QNX List. Luckily, it’s not TOO hard to set up a class to do just that.

First step is to create a class that extends CellRenderer. There’s a lot that seems to go on in CellRenderer but I’m just starting to dig into it so I’ll save that for a later post. The easiest method I found was to override the setter for data and then use the setLabel function there. You can pass in whatever string you want to that setLabel function and it will display as the default label with the default font.

One of the issues I’m having is trying to figure out exactly when the data gets set on the CellRenderer component. Some of the other things I tried (setting it in the constructor, setting it on the drawLabel method) all didn’t work because the data object was still null. So I’m trying to figure out exactly when data becomes available. Hopefully I’ll have that for a followup post that goes into more detail on creating custom renderers for the list class.

Here’s the code I used for my example:

package com.pintley.components.listClasses
{
import qnx.ui.core.SizeUnit;
import qnx.ui.listClasses.CellRenderer;
import qnx.ui.text.Label;
 
public class BeerItemRenderer extends CellRenderer
{
     private var _beer:Object;
 
     public function BeerItemRenderer()
     {
          super();
     }
 
     override public function set data(value:Object):void
     {
          _beer = value;
          setLabel(_beer.beerName);
     }
}
}

Slides and Demo for ‘Intro to Flex “Hero” Mobile’ Presentation at SDFUG

I had a blast presenting at the San Diego Flash Users Group last week and getting a chance to show off Flex “Hero”‘s mobile features as well as getting to hang out with the SDFUG crew. Big thanks to Chris Griffith and Kyle Tyacke for setting it up and to Andrew Walpole, Aaron Pederson, and James Polanco for the great beer opportunities.

I got a chance tonight to upload my slides to Slideshare. They can be found here and embedded below. You can also check out the demo app I built, which shows off some of the things I talked about in the deck. It’s here on Github.

Presenting at the San Diego Flash User Group

If you’re in the San Diego area and want to hear a bit about Flex for mobile devices I’ll be presenting on that topic to the San Diego Flash User Group on December 6th at 6:00 in the North Building of the San Diego Art institute.

I’ll be talking about:

  • Introducing Flex “Hero” and the mobile-optimized components
  • UI paradigms in Flex “Hero” for mobile devices
  • Optimizing Flex “Hero” for good performance on devices
  • Using device APIs with Flex “Hero”

I’ll also be around Southern California for a bit afterwards so if you want to get together and talk Flash/Flex/AIR or anything else, drop me a line.

What Happens When Your Users Install an AIR For Android Application Without AIR

I’ve gotten this question a couple of times so figured it might be worth a blog post (because I wasn’t sure until I tested it). Now that the AIR runtime is on the Market, there are going to be apps that need it. If you’re one of those application developers who creates one, what’s the user experience for someone who hasn’t yet installed AIR for Android? It’s actually pretty nice.

The application will install just fine without any issues. When the user tries to run that application, they’ll be presented with this screen:

After that, they can click the install link and it will take them to Adobe AIR in the Android Market where they can download and install it. After that, the application will work just fine.

The Camera API and Geolocation Exif Data on AIR for Android

As part of my MAX session, I’ve been playing around with the camera API and wanted to pull some of the Exif data around geolocation. My first thought was that I could use the geolocation APIs in AIR to inject Exif data into the image from the camera. But the way that the AIR for Android Camera API works (which makes sense) is that when you take a picture, it creates a MediaPromise, which is a new class in AIR for Android that is similar to a FilePromise. That code includes a bunch of Exif data that Android adds. The only issue with the GPS coordinates are that they’re in sexagesimal format and need to be converted into decimal.

There are actually two ways to get images into your AIR application. The first is using the flash.media.CameraUI class. That brings up the camera controls and lets the user take a picture directly. When the user clicks “OK” on the camera, it saves the file to the SD card and then passes the file reference back to AIR where you can program an event handler to respond:

public var cameraUI:CameraUI;
 
protected function onCreationComplete():void
{
 
if(CameraUI.isSupported)
{
cameraUI = new CameraUI();
cameraUI.addEventListener(MediaEvent.COMPLETE,onComplete);
}
 
}

Then all that has to be done is to call the launch() method and that pops up the camera controls. When the user confirms the photo, the MediaEvent.COMPLETE handler deals with the photo. Or in this case, the file reference.

protected function btn_clickHandler(event:MouseEvent):void
{
cameraUI.launch(MediaType.IMAGE);
}

The other way to get access to photos is to pull them from the phone’s memory. You can do that with the flash.media.CameraRoll API. It’s a very similar process to the CameraUI. Instead of a complete event, listen for a select event, and to bring up the library of images, call the browseForImage() method.

public var cameraRoll:CameraRoll;
 
protected function onCreationComplete():void
{
if(CameraRoll.supportsBrowseForImage)
{
cameraRoll = new CameraRoll();
cameraRoll.addEventListener(MediaEvent.SELECT,onSelect);
}
}
 
protected function btn_clickHandler(event:MouseEvent):void
{
cameraRoll.browseForImage();
}

Now once the image has been taken or selected, we can pull the Exif data from it. Both the complete event and the select event will look the same because they both create a MediaPromise. I’m using the Exif library here, which uses the load() method and an event handler to deal with the Exif data when it loads.

protected function onSelect(event:MediaEvent):void
{
var request:URLRequest = new URLRequest(event.data.file.url);
var exif:ExifLoader = new ExifLoader();
exif.addEventListener(Event.COMPLETE,onExifComplete);
exif.load(request);
}

The parsing of the Exif data is pretty straightforward. Once it has been parsed, pulling out the specific tags by name for Latitude and Longitude, all that is left is to convert the sexagesimal latitude and longitude to decimal degrees.

protected function onExifComplete(event:Event):void
{
var exif:ExifInfo = event.currentTarget.exif as ExifInfo;
var gpsIfd:IFD = exif.ifds.gps;
 
// get the array of GPS coordinates from the Exif data
var exifLat:Array = gpsIfd["GPSLatitude"] as Array;
var exifLon:Array = gpsIfd["GPSLongitude"] as Array;
 
// get the decimal degrees for latitude/longitude
var latitude:Number = convertSexagesimalToDecimal(exifLat[0],exifLat[1],exifLat[2],gpsIfd["GPSLatitudeRef"]);
var longitude:Number = convertSexagesimalToDecimal(exifLon[0],exifLon[1],exifLon[2],gpsIfd["GPSLongitudeRef"]);
}
 
protected function convertSexagesimalToDecimal(degrees:int,minutes:int,seconds:Number,reference:String):Number
{
// do the conversion to decimal degrees
var decimal:Number = degrees + (minutes/60) + (seconds / 3600);
 
// figure out whether we need to use negative latitude or longitude
if(reference == "S" || reference == "E")
{
return decimal * -1;
} else {
return decimal;
}
}

So that’s a crash course in using the camera API on AIR for Android and then extracting decimal degrees out of Android’s existing Exif data.

RIM’s PlayBook and Adobe AIR

Yesterday RIM announced their tablet computer, the PlayBook, with an impressive set of specs and what looks like a great form factor. But what I thought was the coolest part of the announcement is that Adobe AIR is going to play a central role in application development on the tablet. While there will be support for Java eventually and developers can use C++ to tie into things like OpenGL, Adobe AIR is the primary way to develop applications for the tablet.

In fact, a lot of the work on the tablet is already being done in AIR. The browser, the application launcher, and a lot of the default applications have been built using Adobe AIR. One of the cool things is that this is just one step in a long evolution of Flash. The company behind the tablet OS, QNX, was acquired by RIM back in April. QNX has long been a partner of Adobe and is one of the experts on porting Flash to different pieces of hardware. So they’ve got a ton of experience working in the guts of Flash and it sounds like a lot of that knowledge went into the AIR integration on the PlayBook.

So if you’re building AIR applications then this is one more place you’ll be able to bring those skills. You can get a jump on development by heading over to the labs page we have set up for the BlackBerry and of course, there will be a lot more good stuff at MAX, so you’ll want keep an eye on news coming out of LA for the latest.

AIR 2 Multitouch Gestures and the 3D Google Maps Flash API

I took some time over the weekend to dive into the multitouch APIs on AIR 2 and built a basic example with the Google Maps 3D API. I wired up the out of the box gestures in AIR 2 to some specific manipulations so that it goes beyond the typical move and pinch gestures that most of the multitouch mapping apps use. You can see the YouTube clip below and grab the source over on GitHub to see how easy it is to use the gesture events in AIR 2.

A couple of great places to look for more multitouch info is Christian Cantrell’s blog and Matt Legrand’s Multitouchup.com. I’m also working on an Android version of the app but there are a couple of kinks to work out.

AIR and Flash Player coming for Android and Mobile Devices

If you’ve been a member of the Adobe/Macromedia community you’ve heard a lot about Flash on mobile devices over the years. After seeing what’s coming, I think this is what you’ve been waiting for. We talked a bit about Flash Player 10.1 for mobile devices at MAX, and having played with a working version on the Nexus One, I think it’s going to be great for people that want to consume bits of Flash content here and there, especially games and video. But what we haven’t talked much about is AIR for mobile devices.

Cross-device Applications

AIR has been a big success on the desktop partly because being able to create an application with native hooks and having it run cross-platform is a big benefit to developers and to end-users who jump around different operating systems. But the mobile landscape is an even bigger minefield. Apple’s phone gets all of the attention, but you’ve got Android out there, RIM’s BlackBerry, Palm Pre, Windows 7, and others. If you come up with a great idea for an application, you have to write it for all of those platforms. Or watch as someone takes your idea and copies it on one of those platforms after you invest all of your time building it for a single platform. AIR for mobile is going to let you use the language and the tools you know to create applications across all of those mobile devices much more easily. We’re starting with AIR mobile for Android and BlackBerry and Kevin Hoyt has a demo video up that shows it in action on the Motorola Droid. And with AIR for mobile you’ll get access to multi-touch, accelerometer, GPS, creating your own gestures, screen orientation, and other device-specific APIs.

Introducing the Mobile RIA

One of the things that’s going to become very important for developers is creating content specifically for the small screen. Tools like Flash CS5 are going to make it very easy to reuse assets and workflow to create both applications and in-browser mobile Flash content. With AIR for mobile you can take the same application and run it on Android, compile it as an application for the iPhone, or deploy it on Mac, Windows, and Linux on the desktop. Depending on the device, you may want to make some small modifications, but you’ll be able to reuse your assets and a bulk of the code to quickly create cross-platform mobile applications with AIR mobile.

Because of the screen size and the very different specifications of each device, it’s going to be critical to customize content as much for a single device as possible and make sure you’re following best practices. There is a good article on creating mobile RIAs over on the Developer Center and Thibault Imbert has put together a great beta paper on optimizing mobile content for mobile devices.

Flash Platform Tools and Workflow

There is always a lot of talk about the future of Flash and which devices it’s on. But the ecosystem of Flash has gone way beyond an animation engine that’s limited to the web browser. No matter what you’re doing, the tools and workflow of the Flash Platform are going to give you the ability to deploy the most creative applications across the most used devices. Some of those applications will be mobile RIAs in the browser and some will be AIR mobile applications that take advantage of native APIs across mobile operating systems. For developers it really is one web, any device, and any kind of application. So get ready to go nuts and show every other developer how mobile applications are supposed to look.

AIR 2 Beta 2 Available – Much Improved Printing Support

If you missed it yesterday, AIR 2 beta 2 is now available on Adobe labs. This release includes some bug fixes, some optimizations, and a few new features including support for TLS/SSL socket communication and much improved support for interacting with printers. I sat down with the engineer who did a lot of the work on the new printing API and interviewed him about it. He also walked me through a demo of the new features. The APIs let you have complete control over printing and customize the experience. It’s worth checking out.

Discussing New Printing Features in the AIR 2 Beta 2 from Ryan Stewart on Vimeo.