Quirks with the Device object

July 9th, 2009

With FL 3.1, Nokia added the Device object to S60 Platform Services (see Dale’s rundown). The best part of the Device object is that it enables FL developers to disable the auto-rotation that plagued FL 3.0 on S60 5th Edition devices. Although there’s probably still some need to have a fallback in case the end-user hasn’t updated to FL 3.1, it seems like Nokia’s doing a good job of making users aware of the update, so hopefully most people will install the update.

I’ve discovered some quirks with the Device object that are worth keeping in mind when using the Device class:

  1. Things seem to work best if you set Stage.scaleMode to "noScale" and Stage.align to "TL". Otherwise you get funky scaling/positioning issues.
  2. However, once you do that, then Stage.height and Stage.width will vary depending on the orientation of the phone when the user starts your application. If the phone’s in portrait mode, then the stage is 360 wide by 640 high, but if it’s in landscape mode, the stage is 640 wide by 360 high. If you’re working on landscape content and the stage size of your FLA file is 640 wide by 360 high, then after you’ve disabled auto-rotation, you need to check to see whether you need to rotate your content. This is pretty simple:
    if (Stage.width < Stage.height)
    {
    _root._rotation = 90;
    _root._x = 360;
    }

    (Or if you’re anti-_root, wrap everything in a ‘content’ movie clip, etc.)
  3. The Device class also affects how your user can interact with input text fields. These are something that have been problematic in Flash Lite since they were introduced; with the Device class, things are getting somewhat better. The one thing to keep in mind is that the orientation of the phone when the user starts your app affects how they can input text. If the phone is held in portrait mode, the user cannot access the full-screen QWERTY keyboard, only the mini QWERTY, handwriting, or ‘keypad’ style of input. But, if the phone is in landscape mode when your app is started, then the user can access full-screen QWERTY (although it may not be the default input mode).

I’ve put together a simple example you can try out on your 5800 to see how this all works. You can try starting the swf in different orientations, and try commenting out the stage width/height check to see what happens if you don’t.


When to save Shared Object data

July 9th, 2009

(I ran up against this problem a couple of months ago, and when it happened again today I’d completely forgotten about how I’d fixed it, so this is more a note-to-self than anything else…)

My past practice has been to write data to the Shared Object right before the fscommand2("quit") call, on the assumption that this would ensure that it would capture the most recent data, and nothing would be lost. This has worked fine up until the Nokia 5800, which handles this kind of strangely.

In the process of testing a game, I transferred the swf to the phone via Bluetooth, so it was in my messaging inbox. When I launched the game from there, it would save the data as expected, and so the data would be waiting for me when I launched the game again. All’s well so far.

Next step was to package the game into a sis file. When it was installed from the sis and launched from the icon in the Apps folder, the game would not save data upon exit. Very odd. Even odder was that if I navigated directly to the installed swf and launched the game from there, it would save data.

My best guess as to the cause of the problem is that the manner in which a swf is started and stopped when it’s installed from a sis file somehow interrupts the normal manner in which this occurs. I’m not sure of the hows or the whys, but this seems to be what’s happening.

Luckily, the fix is pretty simple: just make sure that you’re saving your data a short period of time before the app quits. In my case, to exit the game you return to the main menu, press the ‘quit’ button, then press ‘yes’ on the confirm screen. I modified the code so that the save data function is called when you return to the main menu screen. Even if you press the required buttons fairly quickly, this still gives a second or two for the data to be saved. In my case, that’s plenty of time, but be sure to test your application to make sure it’s sufficient for your app.


Nokia 5800 Landscape bug in Device Central

July 5th, 2009

Working on some landscape-oriented content for the 5800, and happened across a rather annoying bug. I haven’t tested to see if I can reproduce this on a Windows machine, but it occurs in Device Central CS3 and CS4 on the Mac. When I’m in Device Central and rotate the phone (so it’s landscape instead of portrait), the emulator no longer responds to button presses.

To reproduce:

  1. Create a new .fla, and place a button on the stage. Add some behaviour so that you know that you’ve clicked on the button (i.e. configure the ‘down’ state or add an onRelease, etc.).
  2. Test the movie using the Nokia 5800 profile in Device Central. By default, it will start in portrait mode (i.e. screen is taller than it is wide). Click your button to confirm that it works as you’d expect.
  3. Using the buttons in the bottom corner of Device Central, rotate the phone clockwise or counter-clockwise. Now try clicking your button again. The button no longer responds for me at this point. (The file works fine on the actual phone.)

Suggested workaround:

  1. Keep phone in portrait mode, tilt head 90 degrees during testing.
  2. Make appointment with your local massage therapist.


Bitmap Manipulation in Flash Lite

May 29th, 2009

As mentioned previously, Flash Lite 3.1 is available via Application Update on the Nokia 5800. Apart from making FL more web-friendly, 3.1 adds support for some new classes, primarily related to bitmap manipulation (BitmapData, ColorTransform, etc.). I thought I’d play around with these and see how they perform on the 5800.

The results, I think, are pretty encouraging. You can download this file and try it for yourself. When the app starts, after you’ve taken a moment to note just how darn cute my son is, you can use the sliders to mess around with the alpha, red, green, and blue values of the image. The response is pretty peppy. (The slider itself is a little flaky, since the onReleaseOutside event doesn’t get called consistently, it seems; I’d recommend using the stylus.)

If you hit ‘next’, the swf will take the original image and create a mirror of it using BitmapData.copyPixels(). I haven’t run this many times, but the process was taking around 3/10ths of a second on my 5800 – obviously slower than on the desktop, but a pretty respectable length of time for an image that’s 360px wide by 270px high. With images of any significant size, you wouldn’t be able to use this to create any kind of real-time effects/animations. But it seems likely that the 5800 could easily handle such manipulations on a full-screen image without making the player seize up.

Although I haven’t tested it yet, this should work with the Adobe Distributable Player, since it installs Flash Lite 3.1.


Ovi Launches in Australia…

May 25th, 2009

…and I owe a certain Australian a beer at MAX! Dale Rankine of Moket was kind enough to use Poker Solitaire as his test app when reviewing the process of purchase content through Ovi. Hopefully next Dale will demonstrate the use of the ‘send to friend’ button to spread the word about Poker Solitaire to all his friends!


Update to Flash Lite Player on 5800

May 25th, 2009

As you probably know by now if you follow mobile Flash developments, Nokia recently rolled out an update to the Flash Lite player on the 5800, from the default FL 3.0 pre-installed on the device, to FL 3.1. This has been greeted with some mixed reviews from the FL community.

On the plus side, it’s a move toward updating the player without requiring a firmware update, something that’s been required in the past. I don’t know if Nokia has ever released any stats on how many people upgrade the firmware on their device, but my guess is that it’s a very low number. The process isn’t quite as seamless as it is for the iPhone, where you’re presented with information about firmware updates as soon as you plug in the device. Firmware upgrades on Nokia phones are “hidden”, accessible through a separate app that can be launched from within PC Suite but requiring the user to actively check for updates. My guess is that this keeps updates down.

So the new process is certainly easier, even though the experience could still be improved – the update is now accessible through the Application Update application on the phone. While I don’t claim to be an expert in the intricacies of S60, I have had an S60 phone for the last 4-odd years, and I couldn’t find this application (it’s not part of the Application Manager set of utilities, which to me is the obvious place for it; it’s an actually application that shows up in the Applications list, with the somewhat cryptic title of “App. Upd.”

On the downside, there’s the fragmentation issue, since it means that two people with the same device may have different versions of the FL player installed. This isn’t so much worse than the current situation of FL player upgrades via firmware – it may exacerbate the situation since it’s somewhat easier to upgrade, but the situation still exists. So you can either target the lowest common denominator, or target FL 3.1 in the hopes of driving users to upgrade. Ultimately, it comes down to whether the new features in 3.1 are crucial to your application, or would just be bells and whistles.

You can download a very thorough matrix of player capabilities from the Adobe Developer Connection. The more significant addition, from the perspective of the standalone player, is the addition of some degree of support for the BitmapData, ColorTransform, Matrix, Point, Rectangle, and Transform classes (there are other differences that would impact web browsing more than standalone apps). This little hack can be used to determine which player version is running on a particular device:

var localConnection:LocalConnection = new LocalConnection();
if (localConnection) {
 // FL 3.1
} else {
 // FL 3.0
}

You could either build this into a pre-loader that would serve up a specific swf, or within the app to take different actions depending on the player version.


Talkin' Flash at the Smackdown

May 19th, 2009

Been too busy to even blog about it, but in just a few hours time I’ll be representing the Flash side at a ‘Flash v. Silverlight’ event that’s being co-presented by New Media Manitoba, the Winnipeg .Net User Group, and Flash in the Peg, the Adobe User Group in Winnipeg that I run. The level of interest in the event has been amazing, with over 150 people registered. I’ll be talking about workflow, video, and AIR; hoping to squeeze in a brief mention of mobile in my introductory remarks. It’ll be the largest crowd I’ve ever spoken in front of, so it should be interesting!


ADC Article on creating a List component

May 5th, 2009

A tutorial I wrote on creating a list component for use in Flash Lite applications is now available at the Adobe Developer Connection. I had initially created it because I’d been helping another FL developer who was using a list component from one of the component sets that are available for Flash Lite. Ultimately I realized that it would be quicker for me to replicate the behaviour in that component, but in a simplified form that would be much easier to modify. The list that I created is completely customizable, so you can really leverage Flash’s graphics and animation capabilities to make it completely fit the look and feel of your application. I hope you find it useful to your Flash Lite application development!


Input text fields and the accelerometer on the Nokia 5800

May 1st, 2009

In theory, inline input text fields in Flash Lite are a great idea – by keeping the user within your Flash Lite app, it maintains a consistency of user experience. The downside of inline input text is that when the text field has focus, it essentially “freezes” your Flash Lite app. One of the side effects of this is that the soft keys are returned to their default state, so if the user presses the right soft key, they will exit your app. This happens immediately and without warning, and happens even if you’ve remapped the soft keys to perform some other function. This is not an optimal user experience.

In the process of porting a game to the Nokia 5800, I discovered another unfortunate side effect of this freezing: the manner in which Flash Lite responds to the accelerometer is also returned to its default state. By default, FL on the 5800 will rotate your content if the user rotates their phone from portait to landscape orientation. If you do nothing to account for this, the result is that your content will be scaled down to fit the new stage size. In other words, if your default stage in your SWF is 360 x 640, the new stage size is 640 pixels across by 360 pixels high. Because the default value of Stage.scaleMode is “showAll” and Stage.align is to center the content in the player, your content gets shrunk down and centered.

There are at least a couple of ways to deal with this, but the approach I took was to use the Nokia Platform Services that are available on S60 5th Edition devices to listen for changes in the device orientation, and then modify the orientation of the app to counteract the orientation change. This method involves using the code available at the Forum Nokia wiki, and then changing the callback function in your app to nullify the default behaviour of the player. You also need to override the defaults for Stage.scaleMode and Stage.align.

Once you’ve done this, your application will remain in portrait mode, even if the user changes the orientation of their devices. (There are other ways to do this, and this may not even be the best way, but it works reasonably well.) The problem is that if an input text field has focus, the callback function fails to fire because the Flash Lite player is paused, and so the default behaviour will be restored. This can result is some unpleasant results with your UI. This does not happen when the user first touches the text field, but after they have entered their text and are returned to your application from the system text entry screen.

Eventually, I came up with a workaround, which is simply to keep the most important UI elements always on-screen:

In this image, the green rectangle represents the phone in portrait orientation, and the orange rectangle is landscape. The content in the red square the “necessary” content for the user to see and interact with. By placing it in the top of the screen, this ensures that it’s always visible regardless of device orientation. But this also leaves a bunch of empty space either below or beside it. I eventually filled this empty space with some content/info that the user didn’t particularly need to see on this screen, but was in keeping with the application. If you have access to a 5800, you can see this method in action in this example, which illustrates both the method for keeping the app in portrait orientation and for dealing with the player pausing issue. When you start the SWF on your phone:

  1. Try rotating the phone, and notice that the orientation of the screen doesn’t change.
  2. Tap the input text field, which will take you to the text entry screen. Enter some text and press the checkmark button to return to the app.
  3. When you do that, if you’re still holding the phone in landscape mode, you’ll see the alternate content that’s normally off-stage. If you turn the phone back to portrait mode, you’ll see the alternate content you saw before you entered your text.
  4. Tap somewhere on the screen outside of the text field. This un-pauses the app, and the behaviour will return to how it was in step 1.

This isn’t really optimal – ideally, there would be some way to instruct the Flash Lite player to ignore changes in orientation, but at the moment that doesn’t exist. Of course, the irony of this is that the problem is caused by inline text fields, but the Nokia 5800 doesn’t actually have inline text fields in the Flash Player because of the need to bring up the touchscreen keyboard!


Fun with Firmware!

March 31st, 2009

I’d be lying if I didn’t admit that one of the neat things about mobile software development is being an early adopter: getting your hands on the coolest new phones as soon as possible after they’re released. In Canada, this typically means going with unlocked phones from other countries, because Rogers, our GSM monopolist, seems determined to not carry phones until they’ve been around for a year (or more!).

The downside of this is stuff like what I’ve just been through trying to upgrade the firmware on my unlocked Nokia 5800. The new v20 firmware for the 5800 has been out for quite a while, and I finally got around to installing it on my phone. However, trying to install the firmware via both Nokia Software Updater and Firmware Over-The-Air resulted in me being told that my phone, with v11 firmware, was up-to-date. A dastardly lie!

According to the product code on my phone, the device was intended for Malaysia, and some Googling confirmed that the v20 update should be available. But I also found reports of people in Malaysia having problems installing the firmware, and some recommendations to change the product code to a region for which the update was definitely available (along with the standard warnings about how this will void the warranty on your device). So I figured this is what I should try to do.

In the process, I discovered that the product code on my phone had already been changed, such that my 5800 thought it was from Hong Kong, not Malaysia. I assume that this was a product of the original unlocking, but was also causing some unintended problems (e.g. one method of changing the product code that I found on-line simply couldn’t find my phone). I followed these instructions to change my product code, which worked perfectly well for me (but Use At Your Own Risk; I take no responsibility for bricked phones!). Once that was done, Nokia Software Updater finally found my update, and I now have v20 firmware on my device.

The firmware upgrade process itself was wonderfully painless, but man was getting to that point ever a pain in the butt!