The Space For App Developers

Beyond Plain Old HTML Objects

Archive for August, 2011

Bundling AIR 3 runtime in AIR desktop applications

with 24 comments

At the beginning of this week a beta 2 version of the AIR 3 SDK was released. The AIR 3 SDK and AIR 3 runtime will be a major release that will bring a lot of really cool features. One of the features that I’m really excited about is Captive Runtime, which lets you package your applications with a bundled AIR runtime. This is something that was available for the iOS platform from day one, and now it is also supported for both Android devices and desktops.

I think this is a really important feature for AIR. I heard many times from our customers and the community that we need a solution that enables users to install AIR applications without administrator rights. This is a common scenario especially in the enterprise environments where users don’t have full privileges. Also in some other cases it may improve user experience as there is no need to ask the user to install an additional runtime. It will also help when you need to distribute your application on a CD or other media that doesn’t let you use the browser-based badge installer.

Now how do you package your app for both Windows and Mac? It’s really simple. First thing what you need to do is to download and unzip the new SDK from Adobe Labs. Next compile your application either with the command line mxmlc compiler or using Flash Builder. To do it in Flash Builder, right-click your AIR application project, select Export… -> Flash Builder -> Release Build, and complete just the first step of this wizard without finishing it. This will create a bin-release-temp folder under your project directory with a compiled SWF and app descriptor file. Now go to the command line and invoke following adt command from your project/bin-release-temp folder.

On Windows:

c:\path\to\air3sdk\bin\adt.bat -package -storetype pkcs12 -keystore c:\path\to\certificate.p12 -target bundle myapp.exe myapp-app.xml -C . myapp.swf

On Mac:

/path/to/air3sdk/bin/adt -package -storetype pkcs12 -keystore /path/to/certificate.p12 -target bundle myapp.app myapp-app.xml -C . myapp.swf

You will receive slightly different results depending on your platform. On Mac your application is packaged into myapp.app, which is a single Mac package file. You can just double-click it to run the app. Also if you want to introspect its content you can right-click it and select the Show Package Contents option. On Windows you will get myapp.exe folder that has all the runtime files and the executable myapp.exe file in it. Now you can use your favorite installer builder to build a setup package for your application.

Generated folders structure on Windows:

Generated package structure on Mac:

For Android options check out this blog post by my new fellow evangelist Andy Trice.

Written by Piotr Walczyszyn

August 11th, 2011 at 5:49 pm

Posted in Articles,Examples,Releases

Tagged with

Defining custom URL schemes for your AIR mobile applications

with 20 comments

If you’ve ever wondered if you can register your own URL schemes for your AIR mobile applications running on iOS or Android platforms the answer is yes! Actually it is very simple and you can do it by adding few extra lines in the *-app.xml document. Once you do your application can be invoked directly from other applications or browser with a simple <a href="my-scheme:">open app</a> link click.

(Custom URL schemes are especially useful if you are doing OAuth authentication in your app and you want to redirect the user back to your application after the authorization in the browser. You can find out more about OAuth in AS3/Flex applications in my ADC tutorials.)

To register a custom URL scheme like my-scheme: you simply add the following code in your *-app.xml.

Android settings:

<android>
    <manifestAdditions>
    <![CDATA[
        <manifest android:installLocation="auto">
            <application> 
                <activity> 
                    <intent-filter> 
                        <action android:name="android.intent.action.VIEW"/> 
                        <category android:name="android.intent.category.BROWSABLE"/> 
                        <category android:name="android.intent.category.DEFAULT"/> 
                        <data android:scheme="my-scheme"/> 
                    </intent-filter> 
                </activity> 
            </application> 
 
            <uses-permission android:name="android.permission.INTERNET"/>
 
        </manifest>
    ]]>
    </manifestAdditions>
</android>

iOS settings:

<iPhone>
	<InfoAdditions>
	<![CDATA[
		<key>UIDeviceFamily</key>
		<array>
			<string>1</string>
			<string>2</string>
		</array>
 
		<key>CFBundleURLTypes</key>
		<array>
			<dict>
				<key>CFBundleURLSchemes</key>
				<array>
					<string>my-scheme</string>
				</array>
				<key>CFBundleURLName</key>
				<string>com.myapp</string>
			</dict>
		</array>
 
	]]>
	</InfoAdditions>
        <requestedDisplayResolution>high</requestedDisplayResolution>
</iPhone>

Also you can pass additional arguments to your app from the invoking source. Arguments can be passed in the URL scheme after the colon; for example: my-scheme:myparam. Then in your application you can listen for InvokeEvent.INVOKE event on the NativeApplication.nativeApplication instance. The received event object contains an arguments property that returns an Array with the invoking scheme and parameters in the first item, so it would be my-scheme:myparam value. Next you can parse the value of your argument, and take some action in the application based on its value.

In a Flex Mobile app you can register an InvokeEvent.INVOKE event listener in the preinitialize phase as in following snippet:

 
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   preinitialize="application_preinitializeHandler(event)">
 
	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
 
			protected function application_preinitializeHandler(event:FlexEvent):void
			{
				NativeApplication.nativeApplication.addEventListener(
					InvokeEvent.INVOKE, onInvoke);
			}
 
			private function onInvoke(event:InvokeEvent):void
			{
				// You can parse argument value from event.arguments property
				lblArguments.text = "Arguments: " + event.arguments;
			}
 
		]]>
	</fx:Script>
 
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
 
	<s:Label id="lblArguments" horizontalCenter="0" verticalCenter="0" />
 
</s:Application>

One caveat is that invoking other apps with the custom URL schemes from AIR apps is not possible. The AIR security model is more restrictive and it limits schemes to: http:, https:, sms:, tel:, mailto:, file:, app:, app-storage:, vipaccess: and connectpro:. You can find more about it here and here.

Written by Piotr Walczyszyn

August 2nd, 2011 at 5:15 pm

Posted in Articles,Examples

Tagged with , ,