Monday, November 22, 2010

Using screen orientation APIs for smartphone application development

When you develop application for smartphones, you cannot take for granted the physical orientation of the actual device—as you can, of course, when developing apps for desktops. Accelerometers are increasingly being included in smartphones and enable them to detect motion, vibration, and physical orientation. Accelerometers are increasingly being included in smart phones and enable them to detect motion, vibration, and physical orientation. Adobe AIR 2 includes APIs to access that data.

In Adobe AIR 2, two sets of APIs enable you to use accelerometer data: the screen orientation APIs and the accelerometer APIs. The screen orientation APIs discussed in this article provide properties and methods for dealing with changes in—and accessing information about—the physical orientation of the device. They also provide you with ways to rotate the content or stage on the screen so that it is easier to view on the device. The accelerometer APIs, which are outside of the scope of this article, provide access to the raw data from the accelerometer.

Orientation overview

When utilizing the screen orientation APIs, you must understand two important concepts: the actual physical orientation of the device itself, and the orientation of the screen in relation to the device. The best way to explain this is to look at Figure 1. It is important to note that while they're sometimes related, these two values can be different depending on your application configuration, and there are two different APIs for accessing this information.

Device orientation

Orientation of the app consistent with the device
Figure 1. Orientation of the app is consistent with the device, no matter how it is moved relative to the user. (Photo courtesy of Allen Ellison.)

Physical orientation is the actual orientation of the device in real space. This value is completely independent of anything that is happening in the software or how the content is presented. In ActionScript we access this information from within the Stage class using the deviceOrientation property. The deviceOrientation property is read-only and cannot be changed by the developer at runtime or in the application descriptor file. Valid values for this property can be found on the StageOrientation class and include DEFAULT, ROTATED_LEFT, ROTATED_RIGHT, UPSIDE_DOWN and UNKNOWN.

The value of the deviceOrientation property changes as the device's accelerometer detects movement and changes in the position and orientation of the device. To detect changes to the physical orientation of the device, you can listen for two events that are dispatched when the accelerometer detects changes: StageOrientationEvent.ORIENTATION_CHANGING and StageOrientationEvent.ORIENTATION_CHANGE. The ORIENTATION_CHANGING event is dispatched as the application detects that a change is occurring and before any default behaviors such as auto-orientation (discussed later) actually occur. The ORIENTATION_CHANGE event occurs after any default orientation behaviors occur.

Both events will give you information on the orientation before and after a change in the position or orientation of the device through the afterOrientation and beforeOrientation properties.

Note: There could be a period of time in between these events being dispatched as the operating system changes the actual stage orientation of the content on the device. In the next section I will show you how to change the stage of your application in relation to these events.

Here's how that works in code:

stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging ); stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGE, onOrientationChange ); function onOrientationChanging( event:StageOrientationEvent ):void { trace("The current orientation is " + event.beforeOrientation + " and is about to change to " + event.afterOrientation ); } function onOrientationChange( event:StageOrientationEvent ):void { trace("The orientation was " + event.beforeOrientation + " and is now " + event.afterOrientation ); }

Stage orientation and auto-orientation

While it is important to know and detect changes in the actual device itself, in most cases you will want to update the content on the screen to match the device's orientation and provide the user with a good experience no matter how they are holding the device (see Figure 2).

Auto-orienting the screen in response to movement
Figure 2. Auto-orienting the screen in response to movement, from portrait (left) to landscape (right). (Photo courtesy of Allen Ellison.)

By default, the application will attempt to orient the stage to one of four orientations (DEFAULT, ROTATED_LEFT, ROTATED_RIGHT, UPSIDE_DOWN) to match the physical orientation of the device. This feature is called auto-orientation. The benefit of this behavior is that, as a developer, you will not be required to rotate objects on the display list to display them correctly because the entire stage itself is rotating. Stage resize events will also be dispatched as the stage rotates so that your content can resize appropriately to the new stage size. You will also receive the orientationChanging and orientationChange events as described in the previous section.

In some cases you may want to disable auto-orientation to force the user to use your application in only a single orientation; or you may want to handle resizing the stage and rotating objects yourself. You can accomplish this with the existing APIs in two ways.

First, you can modify the application descriptor file. This requires you to modify the autoOrients property and set it to false. While you will still receive the ORIENTATION_CHANGE and ORIENTATION_CHANGING events when the actual device orientation changes, the stage will not update to try and match that orientation. Here's how this setting would look in the application descriptor file:

... ... false

The second way to prevent the auto-orientation behavior is to listen for the StageOrientationEvent.ORIENTATION_CHANGING event on the stage and call the preventDefault() method on the event object. If you do not call preventDefault(), the stage will auto-orient as expected to the afterOrientation value that is found on the event object. Here's how you'd express that in code:

stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging ); public function onOrientationChanging( event:StageOrientationEvent ):void { event.preventDefault(); }

To detect the current orientation of the stage, use the read-only property orientation on the stage class. By default, the orientation of the stage when applications are deployed to iOS devices will be in the DEFAULT (or portrait) orientation. The application can be set to start in landscape orientation in the application descriptor file. To change this behavior, in the application descriptor file modify or add the tag in the tag with a value of portrait or landscape. When set to landscape, the application opens with the stage in the ROTATED_RIGHT or ROTATED_LEFT orientation:

... ... landscape

You can also modify the stage orientation manually by calling the stage object's setOrientation() method and passing in one of the valid values defined in the StageOrientation class. This method will immediately change the stage orientation independent of the physical device orientation:

stage.setOrientation( StageOrientation.UPSIDE_DOWN );

Sample use cases

By using these configuration settings, properties, and methods, you can support almost any use case when it comes to modifying or detecting changes in screen and device orientation. Here are a few quick examples to illustrate some common use cases.

Supporting landscape mode only

To support landscape mode only, the sole modifications you need to make are to the application descriptor file's autoOrient and orientation properties. This will prevent the application from auto-orienting or changing the stage orientation. While you will still receive events when the physical device orientation changes, the stage will not change orientation during the application lifecycle. Here's how that works in code:

... ... false landscape

Modifying the application when orientation changes

Sometimes you may want to show an entirely different view when the orientation changes instead of just letting the current view resize. To accomplish this you can listen for the orientationChanging event and modify your application and content appropriately:

var landscapeView:MovieClip; var portraitView:MovieClip; stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging ); function onOrientationChanging( event:StageOrientationEvent ):void { var isPortraitView:Boolean = (event.afterOrientation == StageOrientation.UPSIDE_DOWN || event.afterOrientation == StageOrientation.DEFAULT ); portraitView.visible = isPortraitView; landscapeView.visible = !isPortraitView; }

Supporting portrait mode only

In some cases, you may want to support specific orientations of the application, or in this case the DEFAULT and UPSIDE_DOWN orientation of the screen. This way, you will not have to implement a landscape mode for the application, but can allow the device to be held by the user in multiple directions and have the screen update appropriately. The following code implements this:

stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, onOrientationChanging ); function onOrientationChanging( event:StageOrientationEvent ):void { // If the stage is about to move to an orientation we don't support, lets prevent it // from changing to that stage orientation. if(event.afterOrientation == StageOrientation.ROTATED_LEFT || event.afterOrientation == StageOrientation.ROTATED_RIGHT ) event.preventDefault(); }

Original Link

No comments:

Post a Comment