Requirements

Prerequisite knowledge

Some familiarity with Flash Builder, Flex, and ActionScript. For the iOS section, you will need to register as an Apple iOS developer if you want to try this tutorial on your own device.

User level

Intermediate

Additional required other products

  • Esri ArcGIS API for Flex–free download, no license key required to run

  • Download

Location, Location, Location. It’s a motto not just for real estate agents, but also for web pioneers such as Google, Facebook, Foursquare, and countless others that have incorporated location as part of their service offerings. As mobile devices become more ubiquitous and engrained in our everyday lives, applications that combine location awareness, mobility, and mapping assets are providing users with innovative and exciting new capabilities. This new functionality adds to development costs, particularly for developers who are building mobile applications that run on all devices. For these developers Flex and the Flash Platform helps lower those costs and simplifies the development of cross-platform applications by enabling developers to build applications using a single code base and to deploy it onto multiple devices.

In this article, I will show you how to use the ArcGIS API for Flex to build a mapping application that you can deploy on Android and Apple iOS devices. The sample mobile application for this article uses the ArcGIS API for Flex to query a set of US state geometries from ArcGIS.com and display the result as a list of state names when the mobile device is in a portrait orientation, and as a map with the selected states highlighted when the device is in a landscape orientation. Though this application might sound simple, it is not simplistic. It will demonstrate several aspects of the Flex Mobile framework and how it works with the ArcGIS API for Flex.

Importing and running the mapping application

After downloading the sample file for this tutorial, open Flash Builder 4.5.1 and follow these steps:

  1. Choose File > Import > Flash Builder > Flash Builder Project and click Next.
  2. Select File, click Browse, and navigate to the downloaded MobileApp.fxp project file.
  3. Select Import New Copy Of Project and click Finish.

You can run the application using an Android simulator or on a physical Android device. Using the Run Configurations (Run > Run Configuration) you can add a Mobile application and define the Launch Method as appropriate (see Figure 1).

Exploring the application

If you open MobileApp.mxml you can see the source code for the main application.

MobileApp.mxml

<?xml version="1.0" encoding="utf-8"?> <s:ViewNavigatorApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" splashScreenImage="@Embed('/assets/Default.png')" firstView="views.QueryView"> </s:ViewNavigatorApplication>

The application’s main class is a subclass of ViewNavigatorApplication. It has a splashScreenImage property to display an embedded image when the application launches. In addition, it sets the first view of the application (see Figure 2) to an instance of the QueryView class.

The first view (or the home view) enables the user to enter an SQL where clause as a filter to a query task that will fetch US state geometries and names from a REST resource at ArcGIS.com. You can find the source code in QueryView.mxml.

QueryView.mxml

<?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="Query" keyDown="this_keyDownHandler(event)"> <fx:Script> <![CDATA[ private function this_keyDownHandler(event:KeyboardEvent):void { if (event.keyCode === Keyboard.SEARCH) { pushView(); } } private function pushView():void { navigator.pushView(QueryExecuteView, whereInput.text); } ]]> </fx:Script> <s:actionContent> <s:Button icon="@Embed('/assets/search.png')" click="pushView()"/> </s:actionContent> <s:TextInput id="whereInput" width="100%" left="5" right="5" top="10" text="STATE_NAME like 'M%'"/> </s:View>

The QueryView is a subclass of View with its title property set to "Query". It lays out its children vertically. Here, it has only one child, a TextInput instance allowing the user to type in an SQL where clause. A Button instance is defined in the action content section (appearing at the top right of the display) with its icon property referencing an embedded image of a magnifying glass and with a click event handler that will push onto the display an instance of QueryExecuteView, passing as its data property the value of the text input.

In addition, a key down handler is included to react to pressing the hardware search button on the device (on Android devices, this is the search button at the bottom of the device). This too will push an instance of QueryExecuteView.

The QueryExecuteView view (see Figure 3) is an intermediate step to execute the query with the user-defined where clause.

QueryExecuteView.mxml

<?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" xmlns:esri="http://www.esri.com/2008/ags" title="Searching..." viewActivate="queryTask.execute(query)" > <fx:Declarations> <esri:QueryTask id="queryTask" executeComplete="navigator.pushView(QueryResultView, event.featureSet)" showBusyCursor="false" url="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/5" useAMF="true"/> <esri:Query id="query" outFields="['STATE_NAME']" returnGeometry="true" where="{data}"/> </fx:Declarations> <s:BusyIndicator horizontalCenter="0" verticalCenter="0"/> </s:View>

While the query is executing, a busy indidator is displayed to give the user some visual feedback that something is happening. The view declares a QueryTask with its url property set to an ArcGIS REST endpoint with United States demographic data. The property useAMF is set to true indicating that the resulting data will be streamed back to the mobile device in the binary AMF format (rather than the JSON format) for superior performance and payload compression. In addition, the view declares a Query instance with its where property bound to the view data property (remember that was defined in the previous view when navigator.pushView was invoked), the returned field is restricted to only the 'STATE_NAME', and returnGeometry="true" is set to force the return of each state polygon geometry. Upon the view activation, the query task execute function is invoked with the query as an argument. Upon successful execution, a QueryResultView instance is pushed onto the display and its data property will be set to the resulting feature set.

The QueryResultView view displays the result of the query. When the view navigator is instructed to push an instance of that class on the top of the view stack, it creates an instance, invokes its data setter with a reference to a FeatureSet class instance, and renders that view. A FeatureSet has two properties:

  • attributes: An array of objects in which each object has a key/value pair matching the content of the outFields property as defined in the Query.
  • features: An array of Graphic instances in which each graphic has a geometry property.

QueryResultsView.mxml

<?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" xmlns:esri="http://www.esri.com/2008/ags" title.landscape="Feature Map" title.portrait="Feature List"> <fx:Script> <![CDATA[ import com.esri.ags.FeatureSet; import mx.collections.ArrayList; import mx.collections.IList; [Bindable] private var listProvider:IList; override public function set data(value:Object):void { super.data = value; const featureSet:FeatureSet = value as FeatureSet; if (featureSet) { listProvider = new ArrayList(featureSet.attributes); } } ]]> </fx:Script> <s:states> <s:State name="portrait"/> <s:State name="landscape"/> </s:states> <s:navigationContent> <s:Button click="navigator.popToFirstView()" icon="@Embed('/assets/home.png')"/> </s:navigationContent> <s:List id="list" left="0" right="0" top="0" bottom="0" dataProvider="{listProvider}" includeIn="portrait" interactionMode="touch" labelField="STATE_NAME"/> <esri:Map id="map" includeIn="landscape" zoomSliderVisible="false"> <esri:extent> <esri:Extent xmin="-137.6" ymin="19.8" xmax="-50.7" ymax="52.9"/> </esri:extent> <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/> <esri:GraphicsLayer graphicProvider="{data.features}"> <esri:symbol> <esri:SimpleFillSymbol alpha="0.5" color="red"> <esri:outline> <esri:SimpleLineSymbol alpha="1.0" color="yellow"/> </esri:outline> </esri:SimpleFillSymbol> </esri:symbol> </esri:GraphicsLayer> </esri:Map> </s:View>

The view can be in one of two states: portait or landscape. The state of the view is governed by how the user is holding the device. The Flex mobile framework monitors the orientation of the device and sets the state of the view accordingly. This state management enables you to display the query task features based on the orientation. When in the portrait state, the title of the application is set to Feature List and a List instance fills the view (see Figure 4). Each row in the list displays a feature STATE_NAME property value.

When in the landscape state, the list is replaced with a Map instance that is constrained to a geographical area (an extent) showing the lower 48 States. The map is composed of two layers. The first layer is based on a tiling scheme in which the tiles are retreived from the provided URL. The second layer is a GraphicsLayer instance whose data provider is the supplied features in the data property. Each feature or graphic in the graphics layer is symbolized (rendered) using an instance of a SimpleFillSymbol that fills each state with a red color of half transparency and with a solid yellow line as an outline (see Figure 5). To allow the user to navigate back to the home screen, in the navigation content area (top left), a button is added with an icon referencing an image of a home and a click handler instructing the navigator to pop to the first view (in this case, the QueryView).

Packaging a release version of the application

With FlashBuilder 4.5.1, you now have the option of exporting your project directly from the IDE to an Android device, a BlackBerry Tablet OS device, and an iOS device.

To get started, choose Project > Export Release Version and complete the packaging process (see Figure 6).

If you want to deploy to an iOS device (see Figure 7), you must sign up as a developer with Apple and then download a Provisioning Profile file onto your local machine. After the IPA file is generated (which can take some time) drop the IPA file in the release folder onto iTunes and sync your iPhone to transfer the application.

Where to go from here

This article has shown just the very tip of the iceberg for using the ArcGIS API for Flex mobile application development. For more information see: