Starting with AIR for Android and iOS - building one app for both platforms

May 10th, 2011    by sigman    50636
  Tutorials   actionscript, mobile

Nearly half year after I published a quick tutorial on how to set everything up to build AIR apps for Android, I find it pretty much outdated... At that time Flash developers could export their projects for Android using AIR 2.5 and for iOS using PFI (Packager for iPhone) which had functionalities matching AIR 2.0. On March 2011 Adobe have released AIR 2.6, which brings plenty of new features to Android but more importantly it brings them to iOS as well. In this article I will go through steps to create and publish your first simple app for both devices - Android and iPhone using Flash Professional CS5 and AIR 2.6.

Article imported from http://sierakowski.eu/list-of-tips/82-starting-with-air-for-android-and-ios-building-one-app-for-both-platforms.html

By the way, if you are curious why only now Adobe have allowed developers to use the same features for iOS as for Android and what's new in AIR 2.6, follow these links:http://www.adobe.com/devnet/air/articles/ios_features_in_air26.html and http://www.adobe.com/devnet/air/articles/whats-new-in-air-26.html


Before we start

First I want to also explain why I'm going to use command line tool that comes with AIR called ADT (AIR Developer Tool) to publish apps rather than UI which is available in the Flash Professional CS5 IDE. When installing "fresh" Flash CS5, there is only option to create AIR apps (for desktops) or iPhone apps through PFI. But later Adobe provided the "AIR for Android" extension that could be downloaded here http://labs.adobe.com/technologies/flashpro_extensionforair/ that added the UI to set up projects parameters necessary to publish and to use some of the features in your apps. This window is very similar to "iPhone OS Settings" which is built in already to Flash. [UPDATE: AIR for Android Beta extension is no longer available on Adobe Labs website, but you can still find it when googling for "flashpro_extensionforair_p2_112210.zxp" file. This is because Adobe has included it in the Flash Professional CS5.5 which is a paid update if you already have CS5 Frown ]. Below is the screenshot of the AIR for Android Settings window that appears if the extension is installed.

AIR for Android settings

Alhought it is really handy to use it because you don't have to use any command line, just few clicks and application is running on your device, but the problem is that when using it you are publishing with AIR 2.5 and you can't publish with AIR 2.6. [UPDATE: to publish with AIR 2.6 from Flash Professional you need to get the CS5.5 upgrade.]. Adobe usually first releases the new version of ADT (new version of AIR) and then after weeks or months an update to Flash IDE to add it to GUI.

Also there are plenty of options missing there that you could do when manually modifying your application descriptor file or ADT commands, just as quick examples it could be an option to move your app to SD card on Android, publishing with different download URI if you want to publish your Android app on Amazon AppStore, enabling iPhone users to actually close your app rather than pause when pushing the home button and more...

Very important thing to bear in mind is that an app published with AIR 2.6 won't work on every device!

Apps published with AIR 2.6 work on:
- Android OS in version 2.2 or later,
- IOS 4 or later (including iPod Touch 3rd gen and later, iPhone 3gs and later, iPad1 and 2).
If you want your app to be working on older versions of iPhone or iPod, you need to use the old Packager for iPhone tool.


Creating AIR project that works on both platforms

We are going to create a simple app that will check device resolution, create a rectangle that will fill the screen fully horizontally and 60% vertically, display a text field showing which device type app is running on and detected resolution and create a ball that will be controlled by accelerometer. This app is not intended to do any useful things but it is good as an example :)

TestApp source files: http://sierakowski.eu/examples/AIR_Android_iOS/testApp.zip

In order to create app for mobile devices, you need to create a new AIR project (or if you have AIR for Android you can use it - it doesn't really matter as we won't use AIR settings in Flash). Choose "New Document", select "Adobe AIR 2" and save it as the testApp.fla. I'm going to save it to my d:\projects\testapp folder. Within a testapp folder I also created publishing folder where the swf will be published. To set your publishing folder for swf files, go to File -> "Publish Settings" and in Formats tab type "./publishing/testApp.swf" in the File text box for Flash (.swf) field. Next you need to specify project dimensions, I will set 400x400 pixels, it doesn't actually matter as we will adjust it dynamically anyway. The last thing is to create a Document Class called TestApp. At this stage your properties panel should look like on the screenshot below.

Project properties for testApp

Now add the code below to your Document Class - TestApp.as file:

package
{
   import flash.display.StageAlign;
   import flash.display.StageScaleMode;
   import flash.display.Sprite;
   import flash.text.TextField;
   import flash.events.Event;   
   import flash.system.Capabilities;
   import flash.sensors.Accelerometer;
   import flash.events.AccelerometerEvent;
   import flash.events.MouseEvent;
   import flash.desktop.NativeApplication;
   import flash.desktop.SystemIdleMode;
 
   public class TestApp extends Sprite
   {
      private var bcg:Sprite;
      private var ball:Sprite;
      private var info_txt:TextField;
      private var info:String;
      private var stageWidth, stageHeight, heightOffset, accX, accY:Number;
      private var acc:Accelerometer;
 
      public function TestApp() 
      {
         //before we can work with stage object, we need to make sure
         //that it has been added to the display list
         addEventListener(Event.ADDED, init);
 
         //prevent screen dimming
         //Persmissions xml file has to have android.permission.WAKE_LOCK 
         //android.permission.DISABLE_KEYGUARD enabled!
         NativeApplication.nativeApplication.systemIdleMode = 
                                               SystemIdleMode.KEEP_AWAKE;
      }
 
      private function init(e:Event):void
      {
         removeEventListener(Event.ADDED, init);
 
         //stage has no scale, we will lay it out properly
         stage.scaleMode = StageScaleMode.NO_SCALE;
         stage.align = StageAlign.TOP_LEFT;
 
         //as soon as the stage is resized (or app initialised) 
         //we will create our graphics objects
         stage.addEventListener(Event.RESIZE, resize);
      }
 
      private function resize(e:Event):void
      {
         //we don't need to lister for resize event anymore 
         //as the stage orientation is fixed and will not change
         stage.removeEventListener(Event.RESIZE, resize);
 
         //get the fullscreen size of the stage. 
         //It will cover the status bar of Android and iOS
   //On iOS it returns width smaller than height on landscape mode(a bug?)
   //so we need to find a larger value and make it width
         stageWidth = Math.max(stage.fullScreenWidth, stage.fullScreenHeight);
         stageHeight = Math.min(stage.fullScreenWidth, stage.fullScreenHeight);
         heightOffset = stageHeight * .2;
 
         //creating bcg image with full stage width and height 60% of stage height
         bcg = new Sprite();
         bcg.graphics.beginFill(0xcdd6df);
         bcg.graphics.drawRoundRect(0, heightOffset, 
                             stageWidth, stageHeight - 2 * heightOffset, 50, 50);
         bcg.graphics.endFill();
 
         //creating ball image
         ball = new Sprite();
         ball.graphics.beginFill(0xFF0000);
         ball.graphics.drawCircle(0, 0, heightOffset * .5);
         ball.graphics.endFill();
         ball.cacheAsBitmap = true;
         ball.x = stageWidth * .5;
         ball.y = stageHeight - 2 * heightOffset;
 
         //creating text field with some system info
         info = "Detected resolution: " + stageWidth + "x" + stageHeight;
         info += "\nDevice type: " + Capabilities.manufacturer;
         info_txt = new TextField();
         info_txt.width = 200;
         info_txt.text = info;
         info_txt.x = stageWidth * .5 - info_txt.width * .5;
         info_txt.y = stageHeight * .5 - info_txt.height * .5;
 
         //converting vectors to bitmap and adding everything on stage
         bcg.addChild(info_txt);
         bcg.cacheAsBitmap = true;
         addChild(bcg);
         addChild(ball);
 
         //if accelerometer is available then activate it to control the ball
         if (Accelerometer.isSupported)
         {
            acc = new Accelerometer();
            acc.addEventListener(AccelerometerEvent.UPDATE, accUpdate);
            addEventListener(Event.ENTER_FRAME, updateBall);
         }
 
         //if running on everything else than iOS activae exit by touching the ball
         if (Capabilities.manufacturer.indexOf("iOS") == -1)
         {
            ball.addEventListener(MouseEvent.MOUSE_DOWN, 
                      function(){NativeApplication.nativeApplication.exit();});
         }
      }
 
      //handler for accelerometer
      private function accUpdate(e:AccelerometerEvent):void
      {
         accX = e.accelerationX;
         accY = e.accelerationY;
      }
 
      //handler to move the ball
      private function updateBall(e:Event):void
      {
         ball.x -= accX * 30;
         ball.y += accY * 30;
 
         if (ball.x > stageWidth - ball.width * .5)
            ball.x = stageWidth - ball.width * .5;
 
         if (ball.x < ball.width * .5)
            ball.x = ball.width * .5;
 
         if (ball.y >  stageHeight - ball.height * .5)
            ball.y = stageHeight - ball.height * .5;
 
         if (ball.y < ball.height * .5)
            ball.y = ball.height * .5;
      }
   }
}

 

The code above targets both Android and iOS platforms and it disables functionalities that aren't available at runtime. In example, unlike on Android, it is not possible to quit application on iPhone from the application code, the users can do that by pressing the hardware Home button. So our app's code checks what the hardware platform is and if it is not iOS then it adds exit functionality (by touching the ball). If you wanted to use Android Menu or Back keys you would also need to do that in the Android part of your code. Another thing is that we don't want a device to dim the screen when our application is running. To do that we use NativeApplication.systemIdleMode. But in order to use this feature, we need to add (or rather request for) relevant permissions to the Android app descriptor file and we will do that in another step of this tutorial. Application also uses an accelerometer, but before initialising it, we check if its actually available on a device.

To improve performance we are going to use GPU mode and we don't use any vectors but convert them to bitmaps. If we used vectors, which are actually mathematical calculations, the CPU would need to recalculate them every time we move them or if there was any object that overlapped them and moved. If we use bitmaps, this job is done by the GPU and the CPU can concentrate on executing the code and application logic rather than rendering the graphics. So just after creating our sprites, we set cacheAsBitmap property to true which caches these vector sprites as bitmaps. If we also wanted to scale or rotate our objects, we would need to additionally use another property cacheAsBitmapMatrix, otherwise bitmap would need to be recalculated and cached again what would decrease the performance.

matrix:Matrix = new Matrix(); // creates an identity matrix 
mySprite.cacheAsBitmapMatrix = matrix; 
mySprite.cacheAsBitmap = true;

 

Also bear in mind that this method works only on Sprites or MovieClips that don't have any animations. If a MovieClip has frames to play, bitmap will need to be updated for every frame what again kills the performance. In my other projects I actually convert all vectors and movieclips to bitmaps using BitmapData.draw method frame by frame but this is a subject for another article about optimisation that I'm currently working on :) Important thing to note is that when using the GPU mode, any filters or blendmodes will not be displayed.

To learn more about ActionScript APIs specific for mobile development visit: http://help.adobe.com/en_US/as3/iphone/WS789ea67d3e73a8b24b55b57a124b32b5b57-7ffe.html.

Now if you test this project on your computer you will notice that stage size is as you set 400x400 pixels but assets are too big and you can only see a small percent of the actual size. This is because they are dynamically resized to match a full size of a device screen. When you deploy it on your device, it will look correctly. You can use stageWidth and stageHeight when testing on your computer or just make the window fullscreen.

So now once you have your application ready as the swf file has been produced to the d:\project\testApp\publishing folder, the next step is to create application descriptor files, one for Android and one for iOS. They are required by AIR ADT to create and package your apps.


Creating application descriptor files and graphics files for Android and iOS

You wouldn't have to manually create descriptor files if you used GUI available in Flash Professional but creating it once this way and reusing it later enables you to better understand your application and you can also add some features that are not available from the Flash GUI. The "application descriptor" file is a container with settings and information necessary to publish your application the way that will make it compatible with the device's operating system. The convention is that the descriptor file name is constructed by adding "-app" prefix to your app name (ie. yourAppName-app.xml). So in our case it would be TestApp-app.xml.

If you look at the descriptor file for Android and iOS you may realize that we could actually create the same descriptor for both platforms. The difference really is that iOS version requires different icon sizes than Android, besides they have different sections that are platform specific but having them both in the same file won't break anything, the ADT will skip the parts that are not relevant for a chosen platform.

Below is the content of the file, which we name testAppAndroid-app.xml:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<application xmlns="http://ns.adobe.com/air/application/2.6">
  <id>eu.sierakowski.TestApp</id>
  <versionNumber>1.0.0</versionNumber>
  <versionLabel>1.0.0</versionLabel>
  <filename>testApp</filename>
  <description/>
  <name>Test Application</name>
  <copyright/>
 
  <initialWindow>
    <content>testApp.swf</content>
    <systemChrome>standard</systemChrome>
    <transparent>false</transparent>
    <visible>true</visible>
    <fullScreen>true</fullScreen>
    <aspectRatio>landscape</aspectRatio>
    <renderMode>gpu</renderMode>
    <autoOrients>false</autoOrients>
  </initialWindow>
 
  <icon>
    <image36x36>testAppIcon36.png</image36x36>
    <image48x48>testAppIcon48.png</image48x48>
    <image72x72>testAppIcon72.png</image72x72>
  </icon>
 
  <customUpdateUI>false</customUpdateUI>
  <allowBrowserInvocation>false</allowBrowserInvocation>
 
  <android>
    <manifestAdditions>
      <![CDATA[<manifest android:installLocation="auto">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
</manifest>]]>
    </manifestAdditions>
  </android>
</application>

 

What is important in this file is the application namespace which is in the first "application" tag. This means our descriptor is targeted to use AIR 2.6. If you specified AIR 2.5 instead, application would be published as AIR 2.5 (even if publishing with ADT from AIR 2.6) so some optimisation improvements or new features would not be available / included in your app (only important bug-fixes and security changes would be included). If a new version of AIR will be available you should modify your descriptor file to target it.

If you want to learn more what each tag does, check this link: http://help.adobe.com/en_US/air/build/WSfffb011ac560372f2fea1812938a6e463-8000.html.

I'm going to go through only few important tags for our app. The VersionNumber tag defines your application version and it is a number that could be a sequence of up to 3 numbers separated by periods. It is important to pay attention when changing the version number every time you release a new version of your app as only this way the users will be able to upgrade their current version to a new one. This number is recognised when publishing your app to app stores. The VersionLabel tag is a string representation which is not recognised by appstores - it is just to present it to the users in installation dialogs and is not required, if not present the VersionNumber will be used in its place.

We want our app to be fullscreen, have landscape aspect ratio and we don't want it to auto-rotate. These settings are in specified in the initialWindow tag. Also as a render mode we select the GPU to use hardware acceleration for our bitmaps.

In the icons section we provide three types of icons required by Android which are 36x36, 48x48, 72x72. The common practice is to create high quality icon first and then scale remaining down. If you don't provide any icon, the default one will be used. It is not enough to specify icons only here in the descriptor file, you will also need to pass them to the ADT command to wrap them to the application package.

Android section is the group of settings specific to the Android platform only. android:installLocation="auto" makes your app movable to SD card (http://sierakowski.eu/list-of-tips/78-how-to-make-air-for-android-app-movable-to-sd-card.html). Currently there is no way to include this option from the Flash IDE.

Very important part of every descriptor file is request for uses-permissions. Every user at the beginning of the installation process is asked to accept the risk of enabling these permission for an app. Rember to use only these permissions that are absolutely necessary for your app to work. In case of our application it is not necessary to ask for WRITE_EXTERNAL_STORAGE as we won't write any data from our app so we should actually remove it (I left it as an example). But we do need DISABLE_KEYGUARD and WAKE_LOCK to disable screen dimming and auto - keyboard locking to make our app permanently present to the user.

Below is the descriptor file that we are going to use when publishing for iOS. You can see that there are almost no differences really, only different icons (29, 48, 57, 72 and 512) and iPhone section. In the iPhone section there is the infoAdditions section, where you can pass keys to request some functionality or behaviours in iOS. <key>UIApplicationExitsOnSuspend</key><true/> will cause that your app will be closed rather than "paused" when pressing the Home button. f you wanted your app to be targeted for iPhone 4 and or for iPad, you will need to request higher resolution and this is also done from the descriptor file settings.

The UIDeviceFamily tag specifies a target device, 1 is fot iPod and iPhone, 2 for iPad. You can have <string>1</string><string>2</string> to have your app working on both type of devices.

Add <requestedDisplayResolution>high</requestedDisplayResolution> tag after </infoAdditions> if you want your app to use high resolution Retina displays (iPhone 4).

To learn more about iOS and Android specific settings follow this link: http://help.adobe.com/en_US/air/build/WSfffb011ac560372f-5d0f4f25128cc9cd0cb-7ffe.html.

Let's name the Apple descriptor file testAppIOS-app.xml.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<application xmlns="http://ns.adobe.com/air/application/2.6">
  <id>eu.sierakowski.TestApp</id>
  <versionNumber>1.0.0</versionNumber>
  <filename>TestApp</filename>
  <description/>
  <name>TestApp</name>
 
  <copyright/>
 
  <initialWindow>
    <content>testApp.swf</content>
    <systemChrome>standard</systemChrome>
    <transparent>false</transparent>
    <visible>true</visible>
    <fullScreen>true</fullScreen>
    <aspectRatio>landscape</aspectRatio>
    <renderMode>gpu</renderMode>
    <autoOrients>false</autoOrients>
  </initialWindow>
 
  <icon>
    <image29x29>testAppIcon29.png</image29x29>
  <image48x48>testAppIcon48.png</image48x48>
    <image57x57>testAppIcon57.png</image57x57>
  <image72x72>testAppIcon72.png</image72x72>
    <image512x512>testAppIcon512.png</image512x512>
  </icon>
 
  <customUpdateUI>false</customUpdateUI>
 
  <allowBrowserInvocation>false</allowBrowserInvocation>
 
  <iPhone>
    <InfoAdditions>
      <![CDATA[
    <key>UIDeviceFamily</key><array><string>1</string></array>
    <key>UIApplicationExitsOnSuspend</key><true/>
    ]]>
    </InfoAdditions>
  </iPhone>
</application>

 

Providing you have the swf file, both descriptor files and you have already created all variations of testApp icons, everything in the same folder which is d:\projects\testapp\publishing, you are still not done yet :)

You are missing the Default.png file - the splash screen for iOS. This file is shown as the first thing when launching your application and will disappear when it is loaded and ready to use. If you don't provide this file, the user will see only a white screen. At the moment there is no splash screen option for Android. There are different splash screen sizes for different version of iDevices. In example iPad will be looking for Default-Landscape.png and Default-Portrait.png files http://blogs.adobe.com/cantrell/archives/2010/11/how-to-build-an-air-application-for-both-the-iphone-and-ipad.html, iPhone 4 Default @ 2x.png. To learn more see "iOS launch images" section of http://help.adobe.com/en_US/air/build/WSfffb011ac560372f-5d0f4f25128cc9cd0cb-7ffe.html and http://developer.apple.com/library/ios/#qa/qa1588/_index.html.


Certificates and provisioning profile for iOS

You are also still missing the certificate file and provisioning profile required when publishing the iOS version.

If you don't have your p12 certificate already you can easily create one from the Flash IDE. Click on Edit button for your Adobe AIR settings in the Properties panel, then select Signature tab and Create button to create and save your certificate (as on the screnshoot below). Now you are done for Android.

Creating a certificate

Unfortunately it is not that simple for iOS. Beside certificate you need to get the provisioning profile from developer.apple.com by signing in to became Apple iOS developer and paying $99. If you want to publish your app just for testing you will need to get UID of your iDevice and provide it when creating your provisioning. It is quite complicated at first. To learn more about the whole process watch Lee Brimelow's video tutorial: http://www.gotoandlearn.com/play.php?id=133.

Ok, once you received your provisioning profile file, you have all of the required prerequisites to publish your app for Android and iOS. Now it is time to download the AIR 2.6 files and build the ADT commands.


Publishing with AIR 2.6 ADT

First you need to download the latest AIR SDK version from Adobe. At the time of writing this article it is the version 2.6. Adobe is working hard on the version 2.7 that is told to significantly improve performance on iOS but the release date is not known yet.

You can download the AIR sdk from here: http://www.adobe.com/products/air/sdk/

Once it is downloaded, unzip it let say to d:\AIR folder.

Using command line may not be that handy as using Flash GUI. There are some tools from the Flash community written in AIR or Java that have graphical interfaces making the whole process easier. You can also create a batch (.bat) file that you could then reuse just by changing some parameters for different projects.

Publishing for Android and iOS is slightly different as you can see below.

First let's create publishForAndroid.bat file and save it in your d:\projects\testapp\publishing folder (Copy and paste it as one line, I divided it to make it easier to read).

d:\air\bin\adt.bat -package -target apk -storetype pkcs12 
-keystore your_own_certificate.p12 testApp.apk testAppAndroid-app.xml 
testApp.swf testAppIcon36.png testAppIcon48.png testAppIcon72.png

 

Now create publishForIOS.bat file, save it in the same folder as before.

d:\air\bin\adt -package -target ipa-ad-hoc -storetype pkcs12 
-keystore your_own_certificate.p12 
-provisioning-profile your_ownProvision.mobileprovision
testApp.ipa testAppiOS-app.xml testApp.swf 
testAppIcon29.png testAppIcon48.png testAppIcon57.png
testAppIcon72.png testAppIcon512.png Default.png

 

I suggest to do not run these batch files directly but execute them from the command prompt console (cmd). This will allow you to see if there are any errors during the publishing (and the error messages are very helpful), batch files run directly would close immediately. Note that when publishing, you will be asked to provide your certificate password, the same one that you specified when creating your p12 key.

Executing publishForAndroid.bat will produce testApp.apk and publishForIOS will produce testApp.ipa.

As you can see both commands are very similar, the difference is the -target parameter which is "apk" for Android and "ipa" for iOS. You could provide different target options that would allow you to package release for debugging, testing with emulator (Android only - learn more: http://flashandroid.mikalesblog.com/?p=21>), or for distribution on app store. When testing a debug version you can actually receive trace outputs from your device which is pretty cool. To learn more follow this link: http://help.adobe.com/en_US/air/build/WS901d38e593cd1bac1e63e3d128cdca935b-8000.html.

For iOS we also need to provide provisioning file, different icons and Default.png and its variations for iPad and/or iPhone 4 (remember about capital D in the file name). If your app (this applies to all platforms) loads other swf files, xml files or image files, they have to be included in the package by providing these file names to ADT. When speaking about loading swf files, iOS version won't execute any code in external swf files, but you probably know about that already?

You probably noticed that publishing for iOS take much more time. The reason is that the publishing for iOS process is completely different. The ActionScript code is converted to a native code using Ahead of Time compilation and the AIR itself is actually included in the package. To learn more visit this link: http://www.adobe.com/devnet/logged_in/abansod_iphone.htmlor this: http://www.mikechambers.com/blog/files/presentations/fitc_amsterdam_2010/flash_iphone_fitc_2010.pdf. This is the reason why ipa files are much bigger when comparing to Android apk files that only contain your app code and assets.

If you are just trying to test your app on iDevice and you don't want to wait so long, you can use interpreter mode:

1
-target ipa-test-interpreter

 

This actually doesn't convert ActionScript byte code but works like AIR on Android, which is that the bytecode is interpreted at runtime. But be carefull, as the performance of interpreter mode and converted code might be different. Also with interpreter you can load external swfs with the code, which is not possible with converted code that you are going to publish to the AppStore.

 

The Android AIR apps force the users to install AIR runtime on their device (the users are asked to do that when trying to run an app and the AIR is not installed yet). [UPDATE (August 2011): Now with AIR 3.0 you can embed the AIR runtimes into the package, learn more: http://www.leebrimelow.com/?p=2954]

After executing both batch files you should see the apk and ipa files in your published folder.

Files structure


Testing on Android devices

To test our app on Android, just plug your device as a disk drive, copy the apk file to your phone and disconnect it or change connection mode to "charge only" to get back access to the SD card. Then launch a file browser (I'm using Astro file manager), browse to the apk file and execute it. This will install the testApp and you should see the new icon in your Applications listing. Now you are ready for testing :)

Android screens

 

[Update March 2012]

Another way to quickly install an app on Android device is to use adb - a part of Andriod SDK. Using this method, you don't need to copy any apk files.

So first go to settings on your Android 4.x device and in Developer options enable USB debugging. On Android 2.x go to Settings, Applications, Development and select USB Debugging.

You don't have to download Android SDK as the adb is also included in the AIR sdk in lib\android\bin folder.

So once you have your device connected, all you do is type this command:

1
adb install <path to your apk file>

 

And after you type it, you should see something like this:

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
2784 KB/s (9796983 bytes in 3.436s)
        pkg: /data/local/tmp/jumpingDroid.apk
Success

 

To print a list of attached devices use:

1
adb devices

 

If you want to use adb install on a Kindle Fire device, follow this tutorial: http://www.jayceooi.com/2011/12/13/how-to-install-kindle-fire-adb-usb-driver/

 

Testing on iOS devices

To publish to iPhone/iPod/iPad you need to use iTunes. The very first step after you plug your iOS device is to drag and drop your provisioning file to iTunes. You won't be able to successfully deploy your app without this step. Next just drag and drop the ipa file to your Library Apps section, then sync your device and the testApp icon will appear on the screen.

iTunes apps

iTunes syncing

Remember that if you want to sync a newer version of your app, you need to remove the old one from your device first. Everybody knows how do that :) if not: press an app icon for a bit longer to see the small cross button that removes selected app (as on the screenshot below).

iPod screens

Youtube video below shows the testApp on HTC Desire (800 x 480 pixels) and iPod Touch (480 x 320 pixels).

 

Submitting to Markets and AppStores

Now when you spent tens of hours testing your app and you are 100% sure it works as expected then you are ready to share it with the world. Publishing to the Android Market is very easy process. You will need to prepare screenshots, icons, description and pay $25 registration fee. The whole process is very simple and your app will be there within minutes. Here is the link to the Android Market: https://market.android.com/publish.

The Amazon Apstore for Android is free now as they just launched it. They actually review your app first, this usually takes a week. Note that you need to change download URL parameter when publishing your AIR app. Learn more here: http://blogs.adobe.com/cantrell/archives/2011/03/air-2-6-applications-and-the-amazon-appstore-for-android.html. The Amazon Appstore link is here: https://developer.amazon.com/help/faq.html

When it comes to publishing to the Apple Appstore, things are slightly more difficult. You need to actually use different provisioning profile when publishing with ADT. AppStore also has the approval process. To learn more read Adobe article: http://www.adobe.com/devnet/flash/articles/app_store_guide.html


Conclusion

This quick but long :) tutorial only scratches the surface of developing mobile AIR apps. So far you have learnt how to create basic configuration files, publish and test simple app on Android and iOS device. The next very important subject to cover is optimisation for mobiles. When I started testing my first apps I was very disappointed seeing them running only 5 frames per second on iPhone. But when learning and testing different optimisation techniques and just experimenting I was able to reach 60 frames per second. My latest project at the time of writing this article is a game called JumpingDroid and I spent more time optimising it than building the actual game logic. You can play it for free from Android Market and Amazon AppStore. The same game is also running very well on iOS devices: http://sierakowski.eu/blog/23-blog/80-jumping-droid-runs-60-frames-per-second-on-ipod-touch-with-air-26.html. I have learnt a lot when building it and I'm currently writing another article about some optimisation tips for mobile AIR apps.

AIR for mobile is a new technology and there aren't many (any?) books and materials yet that would cover everything. There are plenty of very good documentation and blog post provided by Adobe, links to some of them can be found below in the Links section. Also another very good source of solutions for common problems is the official Adobe forum: http://forums.adobe.com/community/air/development/android. There are plenty of community members that are more active then Adobe employees (ie Colin Wink) and I promise you won't be waiting long for an answer (unless your question has been answered 100 times already and you didn't search for answer before posting).

I think the AIR is really great technology, Adobe is spending a lot of effort to put more and more functionalities and to further optimise it. I hope you won't find it very hard to learn and I wish you good luck with your apps and don't forget to share your links to the markets and appstores!

And if you find anything that could be corrected in this article, please also let me know!


What next? - learn optmisation techniques!

If you came to this point then you are ready to move on and create you first game or app. If you want to learn some of the optimisation tips and techniques that I used when developing Jumping Droid game, read this article: http://sierakowski.eu/list-of-tips/86-building-mobile-games-in-adobe-air-optimization-techniques-used-in-jumping-droid-game.html


Links

Links used in this article:

Comments imported from the original article @sierakowski.eu

 
+- 0 #16 stpapadakis 2013-07-30 07:00
Hello. I tried followed your instructions but my flash app stil doesnt' run in full screen mode. Do you have any suggestions?
Quote
 
 
 
+- 0 #15 stpapadakis 2013-07-30 06:54
Hello! I followed your intstructions but i still can make my app play in full screen mode. I used your .as file in my flash file but still nothing happened.
Any suggestions?
Quote
 
 
 
+- 0 #14 EricR 2012-11-30 14:42
I am just beginning my journey of making portable games using Flash. This is an amazingly easy tutorial. Thank you for posting stuff like this!!
Quote
 
 
 
+- 0 #13 jossu 2012-10-13 21:49
Iam using Flash cs6 and i have a "base" movieclip on stage. Still i cant scale it according to different resolutions. could anybody help ?
stageWidth = Math.max(stage.fullScreenWidth , stage.fullScreenHeigh t);
stageHeight = Math.min(stage.fullScreenWidth , stage.fullScreenHeigh t);
heightOffset = stageHeight * .2;

base.width = stageWidth;
base.height = stageHeight;
Quote
 
 
 
+- 0 #12 Sean Smith 2012-09-14 14:25
Holy Crap! You are a very smart man and I have learned so much from you on this and the game optimization post, that my head wants to float off my body and explode! THANK YOU!
Quote
 
 
 
+- 0 #11 kris 2012-05-08 16:03
great tutorial! thanks for tanking your time and sharing!!!
Quote
 
 
 
+- 0 #10 Vinicius Oliveira 2012-01-27 11:05
:lol:
HOW I do WAKE_LOCK in IOS developing, to screen not dim ?
Quote
 
 
 
+- 0 #9 daniel 2012-01-23 12:10
I'm a bit puzzled with this statement:

"If your app (this applies to all platforms) loads other swf files, xml files or image files, they have to be included in the package by providing these file names to ADT. When speaking about loading swf files, iOS version won't execute any code in external swf files, but you probably know about that already?"

I know the limitation of iOS that make it impossible to load an swf file (with code inside) from another sandbox domain (internet) into a running Main (local), but is this true for packed-with-ipa asset-type-swf files as well?

I need to come up with a strategy for an application - and i would love to walk the modular way by loading class definitions into a core. Is that a no-go on iOS, or packing my modules with the ipa would work?

Thank You.
Quote
 
 
 
+- 0 #8 skyser 2012-01-11 15:42
Yes, thank you for this. I was wrestling with basic issues like accessing the fullscreen and getting actual stage resolution. This tut helped me where the Adobe developer connection FAILED!
Quote
 
 
 
+- 0 #7 Felix 2011-09-08 20:47
Great clear steps.

But I get a strange error:"Compilation failed..."

When I publish with flash cs5.5 it works great on iPhone but without including any icons. When i include the incons in flash GUI and publish, iTunes reports synch error: Unknown Error:0xE800000 4C". So i tried this solution with ADT but still get stuck...

Can anyone help? i neet to know what the Compilation failed referes to to be able to narrow the scope of the problem.
Quote
 
 
 
+- 0 #6 Bill Deakin 2011-09-07 16:00
Hi

Very useful tutorial, one of the most comprehensive I've read and I've read a lot of these over the past couple of weeks!

I've followed most of this and have a test app installed and working but I can't get the "Full Screen" option to work!

I set the fullScreen node to full exactly like in your example descriptor file above, but ass soon as the loading screen vanishes the toolbar appears.

So am I doing something wrong, or is this a bug in the adt? Did you manage to hide the toolbar OK?

Cheers

Billy
Quote
 
 
 
+- 0 #5 Tadeu 2011-06-02 15:18
Awsome ! really awsome tutorial!
Thanks Sierakowski
Quote
 
 
 
+- 0 #4 woj 2011-05-27 08:19
@Bjorn Thanks! Difference in size is due to the fact that the AIR itself is packed into the ipa files along with your code and assets. On Android users need to install AIR runtime as a separate app so the actual apk files contain only your code, nothing else and therefore are smaller.
Quote
 
 
 
+- 0 #3 Bjorn 2011-05-27 07:37
Nice tutorial.
I do have a question. Do you know why a ipa file becomes more then 3MB even if my swf is less then 90Kb? When I add my file to the app store it even runs up to 6/7MB. I do use optimisation techniques.
It's hard to find any information about this. Ths same project for Android needs less conversion and runs a lot beter.
Quote
 
 
 
+- 0 #2 Czadu 2011-05-23 20:33
Great resource, thanks for sharing this!
Quote
 
 
 
+- 0 #1 J 2011-05-18 00:28
Awesome tutorial!
Quote