<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>James Ward &#187; Adobe AIR</title>
	<atom:link href="http://www.jamesward.com/category/flash-platform/air/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jamesward.com</link>
	<description>Heroku &#124; Java &#124; Scala &#124; Cloud &#124; Open Source &#124; Linux</description>
	<lastBuildDate>Fri, 03 Feb 2012 19:29:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Extending AIR for Android</title>
		<link>http://www.jamesward.com/2011/05/11/extending-air-for-android/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extending-air-for-android</link>
		<comments>http://www.jamesward.com/2011/05/11/extending-air-for-android/#comments</comments>
		<pubDate>Wed, 11 May 2011 15:06:36 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=2325</guid>
		<description><![CDATA[*** The following is totally unsupported by Adobe *** *** UPDATE: Adobe has officially added native extensions to AIR. I highly recommend you use that approach instead of mine. *** Adobe AIR provides a consistent platform for desktop and mobile apps. While consistency is very important there are times when developers need to extend beyond [...]]]></description>
			<content:encoded><![CDATA[<p><font color="#ff0000">*** The following is totally unsupported by Adobe ***</font><br />
<font color="#ff0000">*** UPDATE: <a href="http://www.adobe.com/devnet/air/articles/extending-air.html">Adobe has officially added native extensions to AIR</a>.  I highly recommend you use that approach instead of mine. ***</font></p>
<p>Adobe AIR provides a consistent platform for desktop and mobile apps.  While consistency is very important there are times when developers need to extend beyond the common APIs.  This article will walk you through how to integrate AIR for Android applications with other native APIs and functionality in the Android SDK.  It covers three common use cases for native extensibility: System Notifications, Widgets, and Application Licensing.</p>
<p>If you’d like to follow along you will need the following prerequisites:</p>
<ul>
<li><a href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flash_builder">Adobe Flash Builder 4.5</a>(which includes the Flex 4.5 SDK and AIR 2.6 SDK)</li>
<li><a href="http://developer.android.com/sdk/index.html">Android SDK</a></li>
<li><a href="http://developer.android.com/sdk/eclipse-adt.html">Android Eclipse Plugin</a></li>
</ul>
<p>Before getting started, a little background will help.  Android applications are distributed as APK files.  An APK file contains the Dalvik executable (dex), which will run on an Android device inside the Dalvik VM.  The Android SDK compiles a Java-like language to dex.</p>
<p>AIR for Android applications are also distributed as APK files.  Inside of these APK files is a small bit of dex that bootstraps the AIR for Android runtime, which then loads and runs the SWF file that is also inside of the APK.  The actual dex class that bootstraps the AIR application is dynamically generated by the <em>adt</em> tool in the AIR SDK.  The class is named AppEntry and its package name depends on the AIR application ID, but it always begins with “air”.  The AppEntry class checks for the existence of the AIR runtime and then launches the AIR application.  The Android descriptor file in an AIR APK specifies that the main application class is the AppEntry class.</p>
<p>To extend AIR for Android applications to include native APIs and Android SDK functionality, you start by creating a SWF file using Flex and then copy that SWF file, the dex classes for AIR for Android, and the required resources into a standard Android project.  By using the original AppEntry class you can still bootstrap the AIR application in the Android project but you can extend that class to gain a startup hook.</p>
<ol>
<li>To get started, download a package with the required dependencies for extending AIR for Android:<br />
<a href="http://www.jamesward.com/downloads/extending_air_for_android-flex_4_5-air_2_6-v_1.zip">http://www.jamesward.com/downloads/extending_air_for_android-flex_4_5-air_2_6-v_1.zip</a></li>
<li>Next, create a regular Android project in Eclipse (do not create an Activity yet):<br />
<img src="http://www.jamesward.com/wp/uploads/2011/05/new_android_project.jpg" alt="" title="New Android Project" width="613" height="905" class="alignnone size-full wp-image-2326" /></li>
<li>Copy all of the files from the zip file you downloaded into the root directory of the newly created Android project.  You will need to overwrite the existing files and update the launch configuration (if Eclipse asks you to).</li>
<li>Delete the “res/layout” directory.</li>
<li>Add the airbootstrap.jar file to the project’s build path.  You can do that by right-clicking on the file, then select Build Path and then Add to Build Path.</li>
<li>Verify that the project runs.  You should see “hello, world” on your Android device.  If so, then the AIR application is properly being bootstrapped and the Flex application in assets/app.swf is correctly being run.
<p>At this point if you do not need any custom startup hooks then you can simply replace the assets/app.swf file with your own SWF file (but it must be named app.swf).  If you do need a custom startup hook then simply create a new Java class named “MainApp” that extends the air.app.AppEntry class.<br />
<img src="http://www.jamesward.com/wp/uploads/2011/05/new_android_class.png" alt="" title="New Android Class" width="652" height="720" class="alignnone size-full wp-image-2327" /></li>
<li>Override the onCreate() method and add your own startup logic before super.onCreate() is called (which loads the AIR app).  Here is an example:

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">package com.<span style="color: #006600;">jamesward</span>;
&nbsp;
<span style="color: #0066CC;">import</span> air.<span style="color: #006600;">app</span>.<span style="color: #006600;">AppEntry</span>;
<span style="color: #0066CC;">import</span> android.<span style="color: #0066CC;">os</span>.<span style="color: #006600;">Bundle</span>;
&nbsp;
<span style="color: #0066CC;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MainApp <span style="color: #0066CC;">extends</span> AppEntry <span style="color: #66cc66;">&#123;</span>
&nbsp;
	<span style="color: #66cc66;">@</span>Override
	<span style="color: #0066CC;">public</span> <span style="color: #0066CC;">void</span> onCreate<span style="color: #66cc66;">&#40;</span>Bundle arg0<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span>
		<span style="color: #0066CC;">System</span>.<span style="color: #006600;">out</span>.<span style="color: #006600;">println</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;test test&quot;</span><span style="color: #66cc66;">&#41;</span>;
		<span style="color: #0066CC;">super</span>.<span style="color: #006600;">onCreate</span><span style="color: #66cc66;">&#40;</span>arg0<span style="color: #66cc66;">&#41;</span>;
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre></div></div>

</li>
<li>Open the AndroidManifest.xml descriptor file and tell it to use the new MainApp class instead of the original AppEntry class.  First change the package to be the same as your MainApp’s package:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;manifest</span> <span style="color: #000066;">package</span>=<span style="color: #ff0000;">&quot;com.jamesward&quot;</span> <span style="color: #000066;">android:versionCode</span>=<span style="color: #ff0000;">&quot;1000000&quot;</span> <span style="color: #000066;">android:versionName</span>=<span style="color: #ff0000;">&quot;1.0.0&quot;</span></span>
<span style="color: #009900;">  <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></pre></div></div>

<p>Also update the activity to use the MainApp class (make sure you have the period before the class name):</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;activity</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;.MainApp&quot;</span></span></pre></div></div>

<p>You can also add any other permissions or settings you might need in the AndroidManifest.xml file.</li>
<li>Save the changes and, when Eclipse prompts you, update the launch configuration.</li>
<li>Run the application and you should again see “hello, world”. This time, however, in LogCat (command line tool or Eclipse view) you should see the “test test” output.  Now that you have a startup hook, you can do some fun stuff!</li>
</ol>
<p><strong>System Notifications and Services</strong></p>
<p>AIR for Android applications don’t yet have an API to do Android system notifications.  But you can add system notifications to your AIR for Android application through a startup hook.  In order for the AIR application to communicate with the native Android APIs you must provide a bridge for the communication.  The simplest way to create that bridge is using a network socket.  The Android application can listen for data on the socket and then read that data and determine if it needs to display a system notification.  Then the AIR application can connect to the socket and send the necessary data.  This is a pretty straightforward example but some security (for instance a key exchange) should be implemented to insure that malicious apps don’t discover and abuse the socket.  Also some logic to determine which socket should be used would likely be necessary.</p>
<ol>
<li>Inside the application section add a new Android Service:</li>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;service</span> <span style="color: #000066;">android:enabled</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;TestService&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

</li>
<li>Since this example uses a Socket you will also need to add the INTERNET permission:</li>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;uses-permission</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;android.permission.INTERNET&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

</li>
<li>You might also want to enable the phone to vibrate when there is a new notification.  If so add that permission as well:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;uses-permission</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;android.permission.VIBRATE&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

</li>
<li>Save your changes to AndroidManifest.xml.</li>
<li>Next, create the background Java Service class, called TestService.  This service will listen on a socket and when necessary, display an Android Notification:

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.jamesward</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.BufferedInputStream</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.DataInputStream</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.IOException</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.ServerSocket</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.net.Socket</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.app.Notification</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.app.NotificationManager</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.app.PendingIntent</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.app.Service</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.content.Context</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.content.Intent</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.os.IBinder</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.os.Looper</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.util.Log</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestService <span style="color: #000000; font-weight: bold;">extends</span> Service
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">boolean</span> stopped<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Thread</span> serverThread<span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">ServerSocket</span> ss<span style="color: #339933;">;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> IBinder onBind<span style="color: #009900;">&#40;</span>Intent intent<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onCreate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onCreate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    Log.<span style="color: #006633;">d</span><span style="color: #009900;">&#40;</span>getClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSimpleName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;onCreate&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      serverThread <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Thread</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Runnable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
                <span style="color: #000000; font-weight: bold;">try</span>
                <span style="color: #009900;">&#123;</span>
                        Looper.<span style="color: #006633;">prepare</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        ss <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ServerSocket</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">12345</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        ss.<span style="color: #006633;">setReuseAddress</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        ss.<span style="color: #006633;">setPerformancePreferences</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>stopped<span style="color: #009900;">&#41;</span>
                        <span style="color: #009900;">&#123;</span>
                                <span style="color: #003399;">Socket</span> accept <span style="color: #339933;">=</span> ss.<span style="color: #006633;">accept</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                                accept.<span style="color: #006633;">setPerformancePreferences</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span>, <span style="color: #cc66cc;">100</span>, <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                                accept.<span style="color: #006633;">setKeepAlive</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                                <span style="color: #003399;">DataInputStream</span> _in <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                                <span style="color: #000000; font-weight: bold;">try</span>
                                <span style="color: #009900;">&#123;</span>
                                        _in <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">DataInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">BufferedInputStream</span><span style="color: #009900;">&#40;</span>accept.<span style="color: #006633;">getInputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>,<span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                                <span style="color: #009900;">&#125;</span>
                                <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e2<span style="color: #009900;">&#41;</span>
                                <span style="color: #009900;">&#123;</span>
                                  e2.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                                <span style="color: #009900;">&#125;</span>
&nbsp;
                                <span style="color: #000066; font-weight: bold;">int</span> method <span style="color: #339933;">=</span>_in.<span style="color: #006633;">readInt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                                <span style="color: #000000; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>method<span style="color: #009900;">&#41;</span>
                                <span style="color: #009900;">&#123;</span>
                                  <span style="color: #666666; font-style: italic;">// notification</span>
                                  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span>
                                        doNotification<span style="color: #009900;">&#40;</span>_in<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                                        <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                                <span style="color: #009900;">&#125;</span>
                        <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Throwable</span> e<span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                        e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        Log.<span style="color: #006633;">e</span><span style="color: #009900;">&#40;</span>getClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSimpleName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;Error in Listener&quot;</span>,e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
                <span style="color: #000000; font-weight: bold;">try</span>
                <span style="color: #009900;">&#123;</span>
                  ss.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
                <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                  Log.<span style="color: #006633;">e</span><span style="color: #009900;">&#40;</span>getClass<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getSimpleName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;keep it simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span>,<span style="color: #0000ff;">&quot;Server thread&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      serverThread.<span style="color: #006633;">start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> doNotification<span style="color: #009900;">&#40;</span><span style="color: #003399;">DataInputStream</span> in<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">IOException</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> id <span style="color: #339933;">=</span> in.<span style="color: #006633;">readUTF</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    displayNotification<span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  @Override
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onDestroy<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          stopped<span style="color: #339933;">=</span><span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
          <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                  ss.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">IOException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
          serverThread.<span style="color: #006633;">interrupt</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
                  serverThread.<span style="color: #006633;">join</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">InterruptedException</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> displayNotification<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> notificationString<span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">int</span> icon <span style="color: #339933;">=</span> R.<span style="color: #006633;">drawable</span>.<span style="color: #006633;">mp_warning_32x32_n</span><span style="color: #339933;">;</span>
    CharSequence tickerText <span style="color: #339933;">=</span> notificationString<span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">long</span> when <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Context</span> context <span style="color: #339933;">=</span> getApplicationContext<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    CharSequence contentTitle <span style="color: #339933;">=</span> notificationString<span style="color: #339933;">;</span>
    CharSequence contentText <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Hello World!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    Intent notificationIntent <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Intent<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, MainApp.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    PendingIntent contentIntent <span style="color: #339933;">=</span> PendingIntent.<span style="color: #006633;">getActivity</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, <span style="color: #cc66cc;">0</span>, notificationIntent, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    Notification notification <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Notification<span style="color: #009900;">&#40;</span>icon, tickerText, when<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    notification.<span style="color: #006633;">vibrate</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">long</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span><span style="color: #cc66cc;">0</span>,<span style="color: #cc66cc;">100</span>,<span style="color: #cc66cc;">200</span>,<span style="color: #cc66cc;">300</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    notification.<span style="color: #006633;">setLatestEventInfo</span><span style="color: #009900;">&#40;</span>context, contentTitle, contentText, contentIntent<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003399;">String</span> ns <span style="color: #339933;">=</span> <span style="color: #003399;">Context</span>.<span style="color: #006633;">NOTIFICATION_SERVICE</span><span style="color: #339933;">;</span>
    NotificationManager mNotificationManager <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>NotificationManager<span style="color: #009900;">&#41;</span> getSystemService<span style="color: #009900;">&#40;</span>ns<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    mNotificationManager.<span style="color: #006633;">notify</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, notification<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This service listens on port 12345. When it receives some data it checks if the first “int” sent is “1”. If so, it then creates a new notification using the next piece of data (a string) that is received over the socket.</li>
<li>Modify the MainApp Java class to start the service when the onCreate() method is called:

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">	@Override
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onCreate<span style="color: #009900;">&#40;</span>Bundle savedInstanceState<span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000000; font-weight: bold;">try</span>
		<span style="color: #009900;">&#123;</span>
			Intent srv <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Intent<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, TestService.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			startService<span style="color: #009900;">&#40;</span>srv<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #666666; font-style: italic;">// service could not be started</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onCreate</span><span style="color: #009900;">&#40;</span>savedInstanceState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span></pre></div></div>

<p>That is all you need to do in the Android application.</li>
<li>Next, create a Flex application that will connect to the socket and send the right data.  Here is some sample code for my Notifier.mxml class, which I used to test the Android service:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Application</span> <span style="color: #000066;">xmlns:fx</span>=<span style="color: #ff0000;">&quot;http://ns.adobe.com/mxml/2009&quot;</span> </span>
<span style="color: #009900;">                       <span style="color: #000066;">xmlns:s</span>=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/spark&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;fx:Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    @namespace s &quot;library://ns.adobe.com/flex/spark&quot;;
&nbsp;
    global {
      fontSize: 32;      
    }
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/fx:Style<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:layout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:VerticalLayout</span> <span style="color: #000066;">horizontalAlign</span>=<span style="color: #ff0000;">&quot;center&quot;</span> <span style="color: #000066;">paddingTop</span>=<span style="color: #ff0000;">&quot;20&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:layout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:TextInput</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;t&quot;</span> <span style="color: #000066;">text</span>=<span style="color: #ff0000;">&quot;test test&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:Button</span> <span style="color: #000066;">label</span>=<span style="color: #ff0000;">&quot;create notification&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;s:click<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #339933;">&lt;![CDATA[</span>
<span style="color: #339933;">        var s:Socket = new Socket();</span>
<span style="color: #339933;">        s.connect(&quot;localhost&quot;, 12345);</span>
<span style="color: #339933;">        s.addEventListener(Event.CONNECT, function(event:Event):void {</span>
<span style="color: #339933;">          trace('connected!');</span>
<span style="color: #339933;">          (event.currentTarget as Socket).writeInt(1);</span>
<span style="color: #339933;">          (event.currentTarget as Socket).writeUTF(t.text);</span>
<span style="color: #339933;">          (event.currentTarget as Socket).flush();</span>
<span style="color: #339933;">          (event.currentTarget as Socket).close();</span>
<span style="color: #339933;">        });</span>
<span style="color: #339933;">        s.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent):void {</span>
<span style="color: #339933;">          trace('error! ' + event.errorID);</span>
<span style="color: #339933;">        });</span>
<span style="color: #339933;">        s.addEventListener(ProgressEvent.SOCKET_DATA, function(event:ProgressEvent):void {</span>
<span style="color: #339933;">          trace('progress ');</span>
<span style="color: #339933;">        });</span>
<span style="color: #339933;">      ]]&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:click<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Button<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/s:Application<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As you can see there is just a TextInput control that allows the user to enter some text.  Then when the user clicks the Button the AIR for Android application connects to a local socket on port 12345, writes an int with the value of 1, writes the string that the user typed into the TextInput control, and finally flushes and closes the connection.  This causes the notification to be displayed.</li>
<li>Now simply compile the Flex app and overwrite the assets/app.swf file with the new Flex application.  Check out a <a href="http://www.youtube.com/watch?v=HjDu66NOpuA">video demonstration</a> of this code.</li>
</ol>
<p><strong>Widgets</strong></p>
<p>Widgets in Android are the mini apps that can be displayed on the home screen of the device.  There is a fairly limited amount of things that can be displayed in Widgets.  So unfortunately Widgets can’t be built with AIR for Android.  However a custom application Widget can be packaged with an AIR for Android application.  To add a Widget to an AIR for Android application you can use the default AppEntry class instead of wrapping it with another class (MainApp in my example).  (It doesn’t, however, do any harm to keep the MainApp class there.)  To add a Widget simply add its definition to the AndroidManifest.xml file, create the Widget with Java, and create a corresponding layout resource.  </p>
<ol>
<li>First define the Widget in the application section of the AndroidManifest.xml file:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;receiver</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;.AndroidWidget&quot;</span> <span style="color: #000066;">android:label</span>=<span style="color: #ff0000;">&quot;app&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;intent-filter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;action</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;android.appwidget.action.APPWIDGET_UPDATE&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/intent-filter<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta-data</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;android.appwidget.provider&quot;</span> <span style="color: #000066;">android:resource</span>=<span style="color: #ff0000;">&quot;@xml/airandroidwidget&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/receiver<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

</li>
<li>You need an XML resource that provides metadata about the widget.  Simply create a new file named airandroidwidget.xml in a new res/xml directory with the following contents:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;appwidget-provider</span> <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:minWidth</span>=<span style="color: #ff0000;">&quot;294dp&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:minHeight</span>=<span style="color: #ff0000;">&quot;72dp&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:updatePeriodMillis</span>=<span style="color: #ff0000;">&quot;86400000&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:initialLayout</span>=<span style="color: #ff0000;">&quot;@layout/main&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/appwidget-provider<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This tells the widget to use the main layout resource as the initial layout for the widget.</li>
<li>Create a res/layout/main.xml file that contains a simple text display:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LinearLayout</span> <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:id</span>=<span style="color: #ff0000;">&quot;@+id/widget&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:orientation</span>=<span style="color: #ff0000;">&quot;vertical&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:background</span>=<span style="color: #ff0000;">&quot;#ffffffff&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextView</span>  </span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;wrap_content&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">android:text</span>=<span style="color: #ff0000;">&quot;hello&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/LinearLayout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Next, you’ll need to create the AppWidgetProvider class specified in the AndroidManifest.xml file.</li>
<li>Create a new Java class named AndroidWidget with the following contents:

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.jamesward</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.app.PendingIntent</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.appwidget.AppWidgetManager</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.appwidget.AppWidgetProvider</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.content.Context</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.content.Intent</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.widget.RemoteViews</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.jamesward.MainApp</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> AndroidWidget <span style="color: #000000; font-weight: bold;">extends</span> AppWidgetProvider
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onUpdate<span style="color: #009900;">&#40;</span><span style="color: #003399;">Context</span> context, AppWidgetManager appWidgetManager, <span style="color: #000066; font-weight: bold;">int</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> appWidgetIds<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">int</span> N <span style="color: #339933;">=</span> appWidgetIds.<span style="color: #006633;">length</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Perform this loop procedure for each App Widget that belongs to this provider</span>
        <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i<span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>N<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">int</span> appWidgetId <span style="color: #339933;">=</span> appWidgetIds<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            Intent intent <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Intent<span style="color: #009900;">&#40;</span>context, MainApp.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            intent.<span style="color: #006633;">setAction</span><span style="color: #009900;">&#40;</span>Intent.<span style="color: #006633;">ACTION_MAIN</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            PendingIntent pendingIntent <span style="color: #339933;">=</span> PendingIntent.<span style="color: #006633;">getActivity</span><span style="color: #009900;">&#40;</span>context, <span style="color: #cc66cc;">0</span>, intent, <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            RemoteViews views <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> RemoteViews<span style="color: #009900;">&#40;</span>context.<span style="color: #006633;">getPackageName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, R.<span style="color: #006633;">layout</span>.<span style="color: #006633;">main</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            views.<span style="color: #006633;">setOnClickPendingIntent</span><span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">id</span>.<span style="color: #006633;">widget</span>, pendingIntent<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            appWidgetManager.<span style="color: #006633;">updateAppWidget</span><span style="color: #009900;">&#40;</span>appWidgetId, views<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This class will display the Widget when necessary and register a click handler that will open the MainApp application when the user taps on the Widget.</li>
<li>Run the application to verify that it works.</li>
<li>Now you can add the widget to the home screen by holding down on the home screen and following the Widget wizard.</li>
<li>Verify that tapping the widget launches the AIR application.</li>
</ol>
<p><strong>Application Licensing</strong></p>
<p>Android provides APIs to help you enforce licensing policies for non-free apps in the Android Market.  You might want to go <a href="http://developer.android.com/guide/publishing/licensing.html">read up on Android Licensing</a> before you give this one a try.</p>
<p>To add Application Licensing to you AIR for Android application you first need to follow the steps outlined in the Android documentation. The broad steps are as follows:</p>
<ol>
<li>Set up an Android Market publisher account</li>
<li>Install the Market Licensing Package in the Android SDK</li>
<li>Create a new LVL Android Library Project in Eclipse</li>
<li>Add a Library reference in the Android project to the LVL Android Library</li>
<li>Add the CHECK_LICENSE permission to your Android project’s manifest file:

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;uses-permission</span> <span style="color: #000066;">android:name</span>=<span style="color: #ff0000;">&quot;com.android.vending.CHECK_LICENSE&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

</li>
</ol>
<p>After completing these set up steps, you are ready to update the MainApp Java class to handle validating the license:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.jamesward</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.android.vending.licensing.AESObfuscator</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.android.vending.licensing.LicenseChecker</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.android.vending.licensing.LicenseCheckerCallback</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.android.vending.licensing.ServerManagedPolicy</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">air.Foo.AppEntry</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.os.Bundle</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.os.Handler</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">android.provider.Settings.Secure</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> MainApp <span style="color: #000000; font-weight: bold;">extends</span> AppEntry <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> BASE64_PUBLIC_KEY <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;REPLACE WITH KEY FROM ANDROID MARKET PROFILE&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Generate your own 20 random bytes, and put them here.</span>
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> SALT <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #339933;">-</span><span style="color: #cc66cc;">45</span>, <span style="color: #cc66cc;">12</span>, <span style="color: #cc66cc;">72</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">31</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">8</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">122</span>, <span style="color: #cc66cc;">98</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">24</span>, <span style="color: #cc66cc;">86</span>, <span style="color: #cc66cc;">47</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">65</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">47</span>, <span style="color: #cc66cc;">33</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">99</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">55</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">64</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">114</span>, <span style="color: #cc66cc;">39</span>, <span style="color: #339933;">-</span><span style="color: #cc66cc;">71</span>, <span style="color: #cc66cc;">47</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> LicenseCheckerCallback mLicenseCheckerCallback<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> LicenseChecker mChecker<span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">private</span> Handler mHandler<span style="color: #339933;">;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> onCreate<span style="color: #009900;">&#40;</span>Bundle savedInstanceState<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onCreate</span><span style="color: #009900;">&#40;</span>savedInstanceState<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mHandler <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Handler<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #003399;">String</span> deviceId <span style="color: #339933;">=</span> Secure.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span>getContentResolver<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, Secure.<span style="color: #006633;">ANDROID_ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mLicenseCheckerCallback <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MyLicenseCheckerCallback<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mChecker <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> LicenseChecker<span style="color: #009900;">&#40;</span>
            <span style="color: #000000; font-weight: bold;">this</span>, <span style="color: #000000; font-weight: bold;">new</span> ServerManagedPolicy<span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>,
                <span style="color: #000000; font-weight: bold;">new</span> AESObfuscator<span style="color: #009900;">&#40;</span>SALT, getPackageName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, deviceId<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
            BASE64_PUBLIC_KEY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mChecker.<span style="color: #006633;">checkAccess</span><span style="color: #009900;">&#40;</span>mLicenseCheckerCallback<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000066; font-weight: bold;">void</span> displayFault<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        mHandler.<span style="color: #006633;">post</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Runnable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Cover the screen with a messaging indicating there was a licensing problem</span>
                setContentView<span style="color: #009900;">&#40;</span>R.<span style="color: #006633;">layout</span>.<span style="color: #006633;">main</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">class</span> MyLicenseCheckerCallback <span style="color: #000000; font-weight: bold;">implements</span> LicenseCheckerCallback <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> allow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isFinishing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Don't update UI if Activity is finishing.</span>
                <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #666666; font-style: italic;">// Should allow user access.</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> dontAllow<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isFinishing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Don't update UI if Activity is finishing.</span>
                <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            displayFault<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> applicationError<span style="color: #009900;">&#40;</span>ApplicationErrorCode errorCode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>isFinishing<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Don't update UI if Activity is finishing.</span>
                <span style="color: #000000; font-weight: bold;">return</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> onDestroy<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">onDestroy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mChecker.<span style="color: #006633;">onDestroy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Also add the following to a new res/layout/main.xml file in order to display an error when the license is denied:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;utf-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;LinearLayout</span> <span style="color: #000066;">xmlns:android</span>=<span style="color: #ff0000;">&quot;http://schemas.android.com/apk/res/android&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:orientation</span>=<span style="color: #ff0000;">&quot;vertical&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;TextView</span>  </span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_width</span>=<span style="color: #ff0000;">&quot;fill_parent&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">android:layout_height</span>=<span style="color: #ff0000;">&quot;wrap_content&quot;</span> </span>
<span style="color: #009900;">    <span style="color: #000066;">android:text</span>=<span style="color: #ff0000;">&quot;@string/license_problem&quot;</span></span>
<span style="color: #009900;">    <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/LinearLayout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>The text to display uses a string resource named “license_problem”, which must be added to the res/values/strings.xml file:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;license_problem&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>THERE WAS A PROBLEM LICENSING YOUR APPLICATION!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>When the application runs it will check for a valid license.  If the license comes back as valid then the AIR application will start and run as usual.  However, if there is an invalid license then the application will set the ContentView to the R.layout.main resource, which displays the error message defined in the “license_problem” resource.  To simulate different responses you can change the “Test Response” in your Android Market profile.</p>
<p><strong>The Gory Details</strong><br />
I’ve wrapped up a generated AppEntry class and its resources to make the process of extending AIR for Android fairly easy.  If you are interested in seeing how that is done, I’ve posted all of the <a href="https://github.com/jamesward/extending_air_for_android">source code on github</a>.</p>
<p>Here is an overview of the procedure:</p>
<ol>
<li>Use the AIR SDK to create an AIR for Android APK file.</li>
<li>Use the dex2jar utility to convert the AppEntry dex classes into a JAR file.</li>
<li>Pull the resource classes out of the JAR file so that they don’t conflict with the new resources.</li>
<li>Use apktool to extract the original resources out of the AIR for Android APK file.</li>
<li>Create a single ZIP file containing the airbootstap.jar file, resources, AndroidManifest.xml file, and assets.</li>
</ol>
<p>Now you can simply copy and paste those dependencies into your Android project.</p>
<p><strong>Conclusion</strong><br />
Hopefully this article has helped you to better understand how you can extend AIR for Android applications with Android APIs.  There are still a number of areas where this method can be improved.  For instance, I am currently working with the <a href="http://code.google.com/p/merapi/">Merapi Project</a> developers to get Merapi working with my method of extending AIR for Android.  That will provide a better bridging technique for communicating between the AIR application and Android APIs.  So stay tuned for more information about that.  And let me know if you have any questions!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2011/05/11/extending-air-for-android/feed/</wfw:commentRss>
		<slash:comments>126</slash:comments>
		</item>
		<item>
		<title>P2P in Desktop, Mobile, and Tablet Flex Apps</title>
		<link>http://www.jamesward.com/2010/12/06/p2p-in-desktop-mobile-and-tablet-flex-apps/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=p2p-in-desktop-mobile-and-tablet-flex-apps</link>
		<comments>http://www.jamesward.com/2010/12/06/p2p-in-desktop-mobile-and-tablet-flex-apps/#comments</comments>
		<pubDate>Mon, 06 Dec 2010 21:16:02 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[flexorg]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=2103</guid>
		<description><![CDATA[Using the open source Flex SDK, developers can easily build desktop, mobile, and tablet applications that use Peer to Peer (P2P) communication. I&#8217;ve created a video that walks through demos and code illustrating how to use the P2P APIs in Adobe AIR applications. Check it out: Grab the code for the demos in the video [...]]]></description>
			<content:encoded><![CDATA[<p>Using the open source Flex SDK, developers can easily build desktop, mobile, and tablet applications that use Peer to Peer (P2P) communication.  I&#8217;ve created a video that walks through demos and code illustrating how to use the P2P APIs in Adobe AIR applications.  Check it out:</p>
<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/IwCOwfwUp4w?fs=1&amp;hl=en_US&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IwCOwfwUp4w?fs=1&amp;hl=en_US&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>Grab the code for the demos in the video from <a href="http://github.com/jamesward">github</a>:</p>
<ul>
<li><a href="https://github.com/jamesward/P2Pong">P2Pong</a></li>
<li><a href="https://github.com/jamesward/P2Hancock">P2Hancock</a> (Signature capture over P2P)</li>
</ul>
<p>Just as the video shows, it&#8217;s incredibly easy to use the P2P APIs.  Here is a quick walk through.  First create a new NetConnection that is connected to &#8220;rtmfp:&#8221; like so:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">localNc = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #0066CC;">NetConnection</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
localNc.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>NetStatusEvent.<span style="color: #006600;">NET_STATUS</span>, netStatus<span style="color: #66cc66;">&#41;</span>;
localNc.<span style="color: #0066CC;">connect</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;rtmfp:&quot;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>In the netStatus event listener wait for the &#8220;NetConnection.Connect.Success&#8221; event and then set up the NetGroup:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> netStatus<span style="color: #66cc66;">&#40;</span>event:NetStatusEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>                        
    <span style="color: #b1b100;">switch</span><span style="color: #66cc66;">&#40;</span>event.<span style="color: #006600;">info</span>.<span style="color: #006600;">code</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">case</span> <span style="color: #ff0000;">&quot;NetConnection.Connect.Success&quot;</span>:
            setupGroup<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #b1b100;">break</span>;
    <span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #0066CC;">private</span> <span style="color: #000000; font-weight: bold;">function</span> setupGroup<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span>
<span style="color: #66cc66;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> groupspec:GroupSpecifier = <span style="color: #000000; font-weight: bold;">new</span> GroupSpecifier<span style="color: #66cc66;">&#40;</span>GROUP_ID<span style="color: #66cc66;">&#41;</span>;
    groupspec.<span style="color: #006600;">ipMulticastMemberUpdatesEnabled</span> = <span style="color: #000000; font-weight: bold;">true</span>;
    groupspec.<span style="color: #006600;">multicastEnabled</span> = <span style="color: #000000; font-weight: bold;">true</span>;
    groupspec.<span style="color: #006600;">routingEnabled</span> = <span style="color: #000000; font-weight: bold;">true</span>;
    groupspec.<span style="color: #006600;">postingEnabled</span> = <span style="color: #000000; font-weight: bold;">true</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">// This is a multicast IP address. More info: http://en.wikipedia.org/wiki/Multicast_address</span>
    groupspec.<span style="color: #006600;">addIPMulticastAddress</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;239.254.254.2:30304&quot;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
    netGroup = <span style="color: #000000; font-weight: bold;">new</span> NetGroup<span style="color: #66cc66;">&#40;</span>localNc, groupspec.<span style="color: #006600;">groupspecWithAuthorizations</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
    netGroup.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>NetStatusEvent.<span style="color: #006600;">NET_STATUS</span>, netStatus<span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>Now handle a &#8220;NetGroup.SendTo.Notify&#8221; event when a message is received over the P2P connection:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">// in the netStatus switch block</span>
<span style="color: #b1b100;">case</span> <span style="color: #ff0000;">&quot;NetGroup.SendTo.Notify&quot;</span>:
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #0066CC;">data</span>:<span style="color: #0066CC;">Object</span> = event.<span style="color: #006600;">info</span>.<span style="color: #0066CC;">message</span>;
    <span style="color: #b1b100;">break</span>;</pre></div></div>

<p>And finally to send a P2P message to everyone who is listening simply do:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">netGroup.<span style="color: #006600;">sendToAllNeighbors</span><span style="color: #66cc66;">&#40;</span>objectToSend<span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>That&#8217;s it!  Super simple and super fun!  :)</p>
<p>Thanks to <a href="http://www.flashrealtime.com/">Tom Krcha</a> for all of his great blogs on how to do this.  Also thanks to Mark Dong and <a href="http://jamesli.cn/blog/">James Li</a> (Flash Platform Evangelists in China) for helping me build P2Pong.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/12/06/p2p-in-desktop-mobile-and-tablet-flex-apps/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Install Adobe AIR on 64-bit Ubuntu 10.10</title>
		<link>http://www.jamesward.com/2010/10/14/install-adobe-air-on-64-bit-ubuntu-10-10/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=install-adobe-air-on-64-bit-ubuntu-10-10</link>
		<comments>http://www.jamesward.com/2010/10/14/install-adobe-air-on-64-bit-ubuntu-10-10/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 14:22:05 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=2064</guid>
		<description><![CDATA[Right now Adobe AIR is only officially available for 32-bit Linux. But it does work on 64-bit Linux with the 32-bit compatibility libraries. There are several ways to install Adobe AIR on Linux. My preferred way on Ubuntu is to use the .deb package. However the .deb package distributed by Adobe can only be installed [...]]]></description>
			<content:encoded><![CDATA[<p>Right now Adobe AIR is only officially available for 32-bit Linux.  But it does work on 64-bit Linux with the 32-bit compatibility libraries.  There are several ways to install Adobe AIR on Linux.  My preferred way on Ubuntu is to use the .deb package.  However the .deb package distributed by Adobe can only be installed on 32-bit systems.  Good news is that this can be easily fixed!  To install the Adobe AIR .deb package on a 64-bit system just follow these steps:</p>
<ol>
<li><a href="http://get.adobe.com/air/">Download the Adobe AIR .deb file</a></a>
<li>In a terminal window go to the directory containing the adobeair.deb file</li>
<li>Create a tmp dir:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> tmp</pre></div></div>

</li>
<li>Extract the deb file to the tmp dir:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">dpkg-deb <span style="color: #660033;">-x</span> adobeair.deb tmp</pre></div></div>

</li>
<li>Extract the control files:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">dpkg-deb <span style="color: #660033;">--control</span> adobeair.deb tmp<span style="color: #000000; font-weight: bold;">/</span>DEBIAN</pre></div></div>

</li>
<li>Change the Architecture parameter from &#8220;i386&#8243; to &#8220;all&#8221;:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">&quot;s/i386/all/&quot;</span> tmp<span style="color: #000000; font-weight: bold;">/</span>DEBIAN<span style="color: #000000; font-weight: bold;">/</span>control</pre></div></div>

</li>
<li>Repackage the deb file:

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">-b</span> tmp adobeair_64.deb</pre></div></div>

</li>
</ol>
<p>Now you can install Adobe AIR on a 64-bit system!  From the command line just do:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">dpkg</span> <span style="color: #660033;">-i</span> adobeair_64.deb</pre></div></div>

<p>That&#8217;s it!  Let me know if you have any questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/10/14/install-adobe-air-on-64-bit-ubuntu-10-10/feed/</wfw:commentRss>
		<slash:comments>123</slash:comments>
		</item>
		<item>
		<title>Video: Introduction to the New Adobe AIR Launchpad</title>
		<link>http://www.jamesward.com/2010/08/24/video-introduction-to-the-new-adobe-air-launchpad/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=video-introduction-to-the-new-adobe-air-launchpad</link>
		<comments>http://www.jamesward.com/2010/08/24/video-introduction-to-the-new-adobe-air-launchpad/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 16:03:01 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1970</guid>
		<description><![CDATA[I just created a video that walks through the new Adobe AIR Launchpad. The AIR Launchpad is the easiest way to get started building desktop apps with Adobe AIR and Flex. Check it out:]]></description>
			<content:encoded><![CDATA[<p>I just created a video that walks through the new <a href="http://labs.adobe.com/technologies/airlaunchpad/">Adobe AIR Launchpad</a>.  The AIR Launchpad is the easiest way to get started building desktop apps with Adobe AIR and Flex.  Check it out:<br />
<object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/_zHVuWfjLHg?fs=1&amp;hl=en_US&amp;rel=0&amp;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/_zHVuWfjLHg?fs=1&amp;hl=en_US&amp;rel=0&amp;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/08/24/video-introduction-to-the-new-adobe-air-launchpad/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Building Client / Cloud Apps with Flash Builder for Force.com</title>
		<link>http://www.jamesward.com/2010/07/26/building-client-cloud-apps-with-flash-builder-for-force-com/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=building-client-cloud-apps-with-flash-builder-for-force-com</link>
		<comments>http://www.jamesward.com/2010/07/26/building-client-cloud-apps-with-flash-builder-for-force-com/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 19:15:25 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Salesforce.com]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1894</guid>
		<description><![CDATA[I have a theory. The majority of people who use enterprise software today use old school Client / Server apps. We&#8217;ve been trying to move these apps to the web for more than ten years. The ease of deployment of web apps is a clear motivator. Yet the client capabilities of the plain old web [...]]]></description>
			<content:encoded><![CDATA[<p>I have a theory.  The majority of people who use enterprise software today use old school Client / Server apps.  We&#8217;ve been trying to move these apps to the web for more than ten years.  The ease of deployment of web apps is a clear motivator.  Yet the client capabilities of the plain old web browser have not been sufficient for many apps to make the leap.  This is why I love Flex and the Flash Platform.  It provides a way to use web technologies and the web deployment model but adds many of the critical things needed for mission critical apps that people use all day long.</p>
<p>But no one wants to go back to the Client / Server architecture.  We want to embrace Cloud Computing architectures but not lose the client capabilities.  What we really need is the Client / Cloud architecture.  We need a web deployment model that provides ease of deployment but also the ability to install applications on our desktops and mobile devices.</p>
<p>This is why I&#8217;m so excited about the new <a href="http://developer.force.com/flashbuilder">Adobe Flash Builder for Force.com</a>.  In a nutshell this is a tool that Adobe and Salesforce.com built together to enable developers to build great software using Flex for the UI and Force.com for the Cloud back-end.  It&#8217;s a wonderful combination of technologies that will help many Client / Server apps make the switch to Client / Cloud.</p>
<p>Applications created with Flash Builder for Force.com can be run in the browser, on the desktop, and on mobile devices.  These applications can be assembled from the hundreds of Flex components that are out there (check out many of them in <a href="http://flex.org/tour">Tour de Flex</a>).</p>
<p>Check out this video to see how to use Flash Builder for Force.com to build a simple app:</p>
<p><object width="640" height="385"><param name="movie" value="http://images.tv.adobe.com/swf/player.swf"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="FlashVars" value="fileID=7230&#038;context=64&#038;embeded=true&#038;environment=production"></param><embed src="http://images.tv.adobe.com/swf/player.swf" flashvars="fileID=7230&#038;context=64&#038;embeded=true&#038;environment=production" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
<p>As you can see, it&#8217;s very easy to get started.  But I wanted to go a step further and try to build something real&#8211;something that shows a genuine use case for extending beyond the out-of-the-box Salesforce.com UI.  I wanted to keep it really simple so that I could post the code here.  What I came up with is this (in user story form):</p>
<ul>
<li>As a Salesforce.com user I want to take a photo, using my phone, of one of my contacts so that the photo can be saved to their contact record for future reference.</li>
<li>As a Salesforce.com user I want to see photos I&#8217;ve taken of my contacts so that I can be reminded of what they look like.</li>
</ul>
<p>Simple enough.  So here is what I came up with:</p>
<p><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/RIUwh6wk8cY&amp;hl=en_US&amp;fs=1?rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/RIUwh6wk8cY&amp;hl=en_US&amp;fs=1?rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object></p>
<p>To build these two apps I first downloaded and installed <a href="https://www.developerforce.com/events/flashbuilder/registration.php">Flash Builder for Force.com</a>.  I used the <a href="http://www.adobe.com/go/airbetasignup">Adobe AIR for Android prerelease</a> to build the mobile app.  Here is how I created these apps.</p>
<p>First I added a new field to Contact to store the photo.  Salesforce.com doesn&#8217;t have a binary field so I used a large text field (32k limit).  I&#8217;ll store the photo Base64 encoded.</p>
<p>Then in Salesforce.com I saved my enterprise.wsdl file. Check out a <a href="http://wiki.developerforce.com/index.php/Demo_Building_Desktop_Client_for_the_Cloud">great video from Dave Carroll</a> to see how to do this.</p>
<p>Now in Flash Builder for Force.com I created a new Force.com Flex Project for the mobile app.  If you do this on your own and want to run on a mobile device then you will need to overlay the AIR for Android SDK on top of a Flex 4.1 SDK.  Select Desktop Application as the app type.  Replace WindowedApplication with just Application.  And replace the F3DesktopApplication with F3WebApplication since F3DesktopApplication uses APIs that are not available on AIR for Android.  (BTW: Flash Builder, Flex, and Force.com Flex Projects do not officially support mobile deployment yet.  It works but there is no support and no guarantees.)  If you are building a standard Web Application or Desktop Application then you can just leave the generated code as is.</p>
<p>Using the Data/Services wizard I connected to Salesforce.com using my enterprise.wsdl file.  After the services and value objects have been generated I modified the Contact object and added a Bindable account property.  The generated application already included the F3DesktopApplication Declaration used to connect to Salesforce.  Due to an incompatibility with that API and AIR for Android I switched it to use F3WebApplication.  In F3WebApplication&#8217;s loginComplete event handler I query Salesforce.com for Accounts and then Contacts, associate contacts with their account, and then store the contacts:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;">app.<span style="color: #006600;">wrapper</span>.<span style="color: #006600;">query</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;select Id, Name from Account&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> AsyncResponder<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">data</span>:ArrayCollection, token:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    accounts = <span style="color: #0066CC;">data</span>;
    app.<span style="color: #006600;">wrapper</span>.<span style="color: #006600;">query</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;select Id, AccountId, FirstName, LastName, Phone, MobilePhone, Email, Title, Department, MailingCity, photoData__c from Contact&quot;</span>, <span style="color: #000000; font-weight: bold;">new</span> AsyncResponder<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">data</span>:ArrayCollection, token:<span style="color: #0066CC;">Object</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #b1b100;">for</span> <span style="color: #b1b100;">each</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> contact:Contact <span style="color: #b1b100;">in</span> <span style="color: #0066CC;">data</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#123;</span>
            <span style="color: #b1b100;">for</span> <span style="color: #b1b100;">each</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">var</span> account:Account <span style="color: #b1b100;">in</span> accounts<span style="color: #66cc66;">&#41;</span>
            <span style="color: #66cc66;">&#123;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>account.<span style="color: #006600;">Id</span> == contact.<span style="color: #006600;">AccountId</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#123;</span>
                    contact.<span style="color: #006600;">account</span> = account;						
                <span style="color: #66cc66;">&#125;</span>
            <span style="color: #66cc66;">&#125;</span>
        <span style="color: #66cc66;">&#125;</span>
        contacts = <span style="color: #0066CC;">data</span>;
    <span style="color: #66cc66;">&#125;</span>, handleError<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span>, handleError<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Notice in the query that I&#8217;m fetching photoData__c, which is the custom field I created on Contact to store the photo.</p>
<p>In the renderer for a contact I need to either display the photo if there is one or let the user add one.  Here is the simple UI code to handle that:</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Group</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span> top=<span style="color: #ff0000;">&quot;8&quot;</span> right=<span style="color: #ff0000;">&quot;8&quot;</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Rect</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:fill</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:SolidColor</span> color=<span style="color: #ff0000;">&quot;#cccccc&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:fill</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Rect</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> id=<span style="color: #ff0000;">&quot;addPhoto&quot;</span> text=<span style="color: #ff0000;">&quot;Add a photo&quot;</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span> verticalAlign=<span style="color: #ff0000;">&quot;middle&quot;</span> textAlign=<span style="color: #ff0000;">&quot;center&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:BitmapImage</span> id=<span style="color: #ff0000;">&quot;photo&quot;</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Group</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>When the contact is set I check to see if there is a photo and if so display it:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>contact.<span style="color: #006600;">photoData__c</span> == <span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
    photo.<span style="color: #0066CC;">visible</span> = <span style="color: #000000; font-weight: bold;">false</span>;
    <span style="color: #b1b100;">return</span>;
<span style="color: #66cc66;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span> decoder:Base64Decoder = <span style="color: #000000; font-weight: bold;">new</span> Base64Decoder<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
decoder.<span style="color: #006600;">decode</span><span style="color: #66cc66;">&#40;</span>contact.<span style="color: #006600;">photoData__c</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">var</span> loader:Loader = <span style="color: #000000; font-weight: bold;">new</span> Loader<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
loader.<span style="color: #006600;">contentLoaderInfo</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
    photo.<span style="color: #006600;">source</span> = event.<span style="color: #0066CC;">target</span>.<span style="color: #006600;">content</span>;
    photo.<span style="color: #0066CC;">visible</span> = <span style="color: #000000; font-weight: bold;">true</span>;
<span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
loader.<span style="color: #006600;">loadBytes</span><span style="color: #66cc66;">&#40;</span>decoder.<span style="color: #006600;">toByteArray</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>The data from the photoData__c field is Base64 decoded and then displayed using the Flex BitmapImage component.</p>
<p>Now when the user clicks on the photo or empty photo box I use the AIR for Android CameraUI to grab a photo, resize it, covert it to a PNG, Base64 encode it, set it on the contact, and then save the contact to Salesforce.com:</p>

<div class="wp_syntax"><div class="code"><pre class="actionscript" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span>CameraUI.<span style="color: #006600;">isSupported</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#123;</span>
    cameraUI = <span style="color: #000000; font-weight: bold;">new</span> CameraUI<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
    cameraUI.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>MediaEvent.<span style="color: #006600;">COMPLETE</span>, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>event:MediaEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">var</span> loader:Loader = <span style="color: #000000; font-weight: bold;">new</span> Loader<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
        loader.<span style="color: #0066CC;">load</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> URLRequest<span style="color: #66cc66;">&#40;</span>event.<span style="color: #0066CC;">data</span>.<span style="color: #006600;">file</span>.<span style="color: #0066CC;">url</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
        loader.<span style="color: #006600;">contentLoaderInfo</span>.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>Event.<span style="color: #006600;">COMPLETE</span>, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>event:Event<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #000000; font-weight: bold;">var</span> bitmap:Bitmap = event.<span style="color: #0066CC;">target</span>.<span style="color: #006600;">content</span> as Bitmap;
&nbsp;
            <span style="color: #000000; font-weight: bold;">var</span> result:BitmapData = <span style="color: #000000; font-weight: bold;">new</span> BitmapData<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">46</span>, <span style="color: #cc66cc;">46</span>, <span style="color: #000000; font-weight: bold;">false</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #000000; font-weight: bold;">var</span> matrix:Matrix = <span style="color: #000000; font-weight: bold;">new</span> Matrix<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            matrix.<span style="color: #006600;">scale</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">46</span> <span style="color: #66cc66;">/</span> bitmap.<span style="color: #0066CC;">width</span>, <span style="color: #cc66cc;">46</span> <span style="color: #66cc66;">/</span> bitmap.<span style="color: #0066CC;">height</span><span style="color: #66cc66;">&#41;</span>;
            result.<span style="color: #006600;">draw</span><span style="color: #66cc66;">&#40;</span>bitmap, matrix<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #000000; font-weight: bold;">var</span> pngEncoder:PNGEncoder = <span style="color: #000000; font-weight: bold;">new</span> PNGEncoder<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            <span style="color: #000000; font-weight: bold;">var</span> pngBytes:ByteArray = pngEncoder.<span style="color: #006600;">encode</span><span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span>;
&nbsp;
            <span style="color: #000000; font-weight: bold;">var</span> base64Encoder:Base64Encoder = <span style="color: #000000; font-weight: bold;">new</span> Base64Encoder<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
            base64Encoder.<span style="color: #006600;">encodeBytes</span><span style="color: #66cc66;">&#40;</span>pngBytes<span style="color: #66cc66;">&#41;</span>;
            <span style="color: #000000; font-weight: bold;">var</span> encodedImage:<span style="color: #0066CC;">String</span> = base64Encoder.<span style="color: #0066CC;">flush</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            contact.<span style="color: #006600;">photoData__c</span> = encodedImage;
&nbsp;
            displayPhoto<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
            F3WebApplication.<span style="color: #006600;">getInstance</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">wrapper</span>.<span style="color: #006600;">save</span><span style="color: #66cc66;">&#40;</span>contact, <span style="color: #000000; font-weight: bold;">new</span> AsyncResponder<span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #0066CC;">data</span>:<span style="color: #0066CC;">Object</span>, token:<span style="color: #0066CC;">Object</span>=<span style="color: #000000; font-weight: bold;">null</span><span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
            <span style="color: #66cc66;">&#125;</span>, FlexGlobals.<span style="color: #006600;">topLevelApplication</span>.<span style="color: #006600;">handleError</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
        <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
    cameraUI.<span style="color: #006600;">addEventListener</span><span style="color: #66cc66;">&#40;</span>ErrorEvent.<span style="color: #0066CC;">ERROR</span>, <span style="color: #000000; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>event:ErrorEvent<span style="color: #66cc66;">&#41;</span>:<span style="color: #0066CC;">void</span> <span style="color: #66cc66;">&#123;</span>
        FlexGlobals.<span style="color: #006600;">topLevelApplication</span>.<span style="color: #006600;">handleError</span><span style="color: #66cc66;">&#40;</span>event<span style="color: #66cc66;">&#41;</span>;
    <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;
    cameraUI.<span style="color: #006600;">launch</span><span style="color: #66cc66;">&#40;</span>MediaType.<span style="color: #006600;">IMAGE</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #66cc66;">&#125;</span></pre></div></div>

<p>That&#8217;s it for the mobile app!  I compiled it, exported it to an Android app, and then copied it to my phone.  Pretty simple and as you can see it works!  One limitation with my approach is the 32k limit of the photoData__c field.  However, I think I could easily get around that by striping the Base64 encoded data across multiple fields.  It&#8217;s not ideal but it would work.</p>
<p>To display the photo when I view a contact on Salesforce.com I created a very simple Flex app using another Force.com Flex Project.  I could have also added photo upload to this application but chose to keep it simple.  All it does is display the selected contact&#8217;s photo.  Here is the complete code (after generating the required services in Flash Builder):</p>

<div class="wp_syntax"><div class="code"><pre class="mxml" style="font-family:monospace;"><span style="color: #000000;">&lt;?xml version=<span style="color: #ff0000;">&quot;1.0&quot;</span> encoding=<span style="color: #ff0000;">&quot;utf-8&quot;</span>?<span style="color: #7400FF;">&gt;</span></span>
<span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Application</span> xmlns:fx=<span style="color: #ff0000;">&quot;http://ns.adobe.com/mxml/2009&quot;</span></span>
<span style="color: #000000;">    xmlns:s=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/spark&quot;</span></span>
<span style="color: #000000;">    xmlns:mx=<span style="color: #ff0000;">&quot;library://ns.adobe.com/flex/mx&quot;</span></span>
<span style="color: #000000;">    xmlns:flexforforce=<span style="color: #ff0000;">&quot;http://flexforforce.salesforce.com&quot;</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Script</span><span style="color: #7400FF;">&gt;</span></span>		
    import mx.rpc.AsyncResponder;
    import mx.utils.Base64Decoder;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Script</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;flexforforce:F</span>3WebApplication id=<span style="color: #ff0000;">&quot;app&quot;</span> requiredTypes=<span style="color: #ff0000;">&quot;Contact&quot;</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;flexforforce:loginComplete</span><span style="color: #7400FF;">&gt;</span></span>
                app.wrapper.query(&quot;select photoData__c from Contact where Id = '&quot; + this.parameters.contactId + &quot;'&quot;, new AsyncResponder(function(data:Object, token:Object):void {
                    if (data.length == 1)
                    {
                        if (data[0].photoData__c == null)
                        {
                            photo.visible = false;
                            noPhoto.visible = true;
                            return;
                        }
&nbsp;
                        var decoder:Base64Decoder = new Base64Decoder();
                        decoder.decode(data[0].photoData__c);
&nbsp;
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(event:Event):void {
                            photo.source = event.target.content;
                            photo.visible = true;
                        });
                        loader.loadBytes(decoder.toByteArray());
                    }
                }, function(fault:Object):void {
                    // ignored
                }));
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;/flexforforce:loginComplete</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/flexforforce:F</span>3WebApplication<span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/fx:Declarations</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:applicationComplete</span><span style="color: #7400FF;">&gt;</span></span>
        app.serverUrl = this.parameters.serverUrl;
        app.loginBySessionId(this.parameters.sessionId);
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:applicationComplete</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Rect</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span><span style="color: #7400FF;">&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:fill</span><span style="color: #7400FF;">&gt;</span></span>
            <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:SolidColor</span> color=<span style="color: #ff0000;">&quot;#cccccc&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
        <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:fill</span><span style="color: #7400FF;">&gt;</span></span>
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Rect</span><span style="color: #7400FF;">&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:Label</span> id=<span style="color: #ff0000;">&quot;noPhoto&quot;</span> text=<span style="color: #ff0000;">&quot;No Photo&quot;</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span> textAlign=<span style="color: #ff0000;">&quot;center&quot;</span> verticalAlign=<span style="color: #ff0000;">&quot;middle&quot;</span> visible=<span style="color: #ff0000;">&quot;false&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
    <span style="color: #000000;"><span style="color: #7400FF;">&lt;s:BitmapImage</span> id=<span style="color: #ff0000;">&quot;photo&quot;</span> width=<span style="color: #ff0000;">&quot;92&quot;</span> height=<span style="color: #ff0000;">&quot;92&quot;</span><span style="color: #7400FF;">/&gt;</span></span>
&nbsp;
<span style="color: #000000;"><span style="color: #7400FF;">&lt;/s:Application</span><span style="color: #7400FF;">&gt;</span></span></pre></div></div>

<p>Finally I created a custom S-Control to run the Flex app:</p>

<div class="wp_syntax"><div class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">object</span> <span style="color: #000066;">classid</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;clsid:D27CDB6E-AE6D-11cf-96B8-444553540000&quot;</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ContactPhoto&quot;</span> <span style="color: #000066;">width</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;92&quot;</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;92&quot;</span> </span>
<span style="color: #009900;"><span style="color: #000066;">codebase</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;https://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab&quot;</span>&gt;</span> 
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">param</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;movie&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{!Scontrol.JavaArchive}&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span> 
    <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">param</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;flashvars&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sessionId={!API.Session_ID}&amp;serverUrl={!API.Partner_Server_URL_90}&amp;contactId={!Contact.Id}&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span> 
    <span style="color: #009900;">&lt;embed <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;{!Scontrol.JavaArchive}&quot;</span> <span style="color: #000066;">width</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;92&quot;</span> <span style="color: #000066;">height</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;92&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;ContactPhoto&quot;</span> </span>
<span style="color: #009900;">flashvars<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;sessionId={!API.Session_ID}&amp;serverUrl={!API.Partner_Server_URL_90}&amp;contactId={!Contact.Id}&quot;</span> </span>
<span style="color: #009900;"><span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;application/x-shockwave-flash&quot;</span> </span>
<span style="color: #009900;">pluginspage<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://www.adobe.com/go/getflashplayer&quot;</span>&gt;</span> 
    <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span>embed&gt;</span> 
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">object</span>&gt;</span></pre></div></div>

<p>I uploaded the compiled Flex app to the S-Control and added it to the Contact page.  And that&#8217;s it!  In just a few hours I extended Force.com and built a cool mobile app.  I could also have easily created a desktop widget for browsing contacts and adding photos.  If you are looking for a fun project to use as a way to learn this stuff that would be a good one!  :)</p>
<p>Here are some resources to help you get started with Flash Builder for Force.com:</p>
<ul>
<li><a href="http://wiki.developerforce.com/index.php/Force.com_Flex_Quick_Start_Tutorial">Force.com Flex Quick Start Tutorial</a></li>
<li><a href="http://developerforce.s3.amazonaws.com/website/afb/docs/ASDoc_Flex/index.html">Force.com Flex Project APIs for Web Applications</a></li>
<li><a href="http://developerforce.s3.amazonaws.com/website/afb/docs/ASDoc_AIR/index.html">Force.com Flex Project APIs for Desktop Applications</a></li>
<li><a href="http://developer.force.com/flashbuilder">Numerous other demo applications and tutorials</a></li>
<li><a href="http://github.com/jamesward/MobileContacts">Source code for my mobile contacts demo</a></li>
<li><a href="http://github.com/jamesward/WebContactSControl">Source code for my web contact photo viewer demo</a></li>
</ul>
<p>Have fun building the next generation of software!  Let me know how it goes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/07/26/building-client-cloud-apps-with-flash-builder-for-force-com/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Tour de Flex 2.0 &#8211; Nearly 500 Flex Examples!</title>
		<link>http://www.jamesward.com/2010/06/21/tour-de-flex-2-0-nearly-500-flex-examples/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tour-de-flex-2-0-nearly-500-flex-examples</link>
		<comments>http://www.jamesward.com/2010/06/21/tour-de-flex-2-0-nearly-500-flex-examples/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 15:45:42 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flash Player]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1827</guid>
		<description><![CDATA[Adobe has just launched the new AIR 2 based Tour de Flex version 2.0 which now contains almost 500 Flex examples! The new version has new AIR 2 examples (only available in the AIR version of Tour de Flex) including: File Promises Mass Storage Detection Native Process Open with default app Socket Server Also there [...]]]></description>
			<content:encoded><![CDATA[<p>Adobe has just launched the new AIR 2 based <a href="http://flex.org/tour">Tour de Flex version 2.0</a> which now contains almost 500 Flex examples!  The new version has new AIR 2 examples (only available in the AIR version of Tour de Flex) including:</p>
<ul>
<li>File Promises</li>
<li>Mass Storage Detection</li>
<li>Native Process</li>
<li>Open with default app</li>
<li>Socket Server</li>
</ul>
<p>Also there are some great examples of the new Flash Player 10.1 and AIR 2 APIs including:</p>
<ul>
<li>Gestures</li>
<li>Global Error Handler</li>
<li>Globalization / Internationalization</li>
<li>Microphone access</li>
</ul>
<p>Those are some great examples but my favorite is still <a href="http://dougmccune.com/blog/">Doug McCune&#8217;s</a> <a href="http://www.adobe.com/devnet/flex/tourdeflex/web/#docIndex=0;illustIndex=0;sampleId=16300">Physics Form</a> followed closely by the <a href="http://www.adobe.com/devnet/flex/tourdeflex/web/#docIndex=-1;illustIndex=0;sampleId=14050">real-time Tour de Flex Dashboard</a>.  :)</p>
<p>If you already have Tour de Flex installed then it should auto update to the latest version when you launch it.  Otherwise install it now using the badge installer below.<br />
<iframe width="216" height="182" frameborder=0 scrolling="no" src="http://tourdeflex.adobe.com/badge/"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/06/21/tour-de-flex-2-0-nearly-500-flex-examples/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Flex on Android in Flash Player and AIR</title>
		<link>http://www.jamesward.com/2010/05/21/flex-on-android-in-flash-player-and-air/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flex-on-android-in-flash-player-and-air</link>
		<comments>http://www.jamesward.com/2010/05/21/flex-on-android-in-flash-player-and-air/#comments</comments>
		<pubDate>Fri, 21 May 2010 16:07:18 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flash Player]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1743</guid>
		<description><![CDATA[This week at the Google I/O conference Adobe announced that a Flash Player 10.1 beta and an Adobe AIR prerelease are now available for Android devices. This is really exciting news for those of us building apps on the Flash Platform because now we can begin building apps in Flex for these mobile devices (and [...]]]></description>
			<content:encoded><![CDATA[<p>This week at the Google I/O conference Adobe announced that a Flash Player 10.1 beta and an Adobe AIR prerelease are now available for Android devices.  This is really exciting news for those of us building apps on the Flash Platform because now we can begin building apps in Flex for these mobile devices (and many others coming soon).</p>
<p>Take a look a some of the quick demos I&#8217;ve built with Flex running on Android in Flash Player and AIR:<br />
<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/Zp7leMUo2NY&#038;hl=en_US&#038;fs=1&#038;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Zp7leMUo2NY&#038;hl=en_US&#038;fs=1&#038;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object><br />
You can get the source code for all of these demos from <a href="http://github.com/jamesward">github</a>.</p>
<p>Also <a href="http://coenraets.org">Christophe Coenraets</a> has posted some great Flex mobile demos.  Check out his <a href="http://coenraets.org/blog/2010/05/sample-application-using-flex-and-air-for-android/">Employee Directory</a> and <a href="http://coenraets.org/blog/2010/05/android-trader-application-with-flex-4-and-air/">Stock Trader</a> demos.</p>
<p>These are very exciting times for developers!</p>
<p>If you want to check out the Flash Player 10.1 beta for Android it will be available in the Android Marketplace for Android 2.2 devices.  You can try Adobe AIR for Android today by <a href="http://blogs.adobe.com/air/2010/05/air_android_prerelease.html">signing up for the prerelease</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/05/21/flex-on-android-in-flash-player-and-air/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Video: Build your First Desktop Application with Flash Builder</title>
		<link>http://www.jamesward.com/2010/04/01/video-build-your-first-desktop-application-with-flash-builder/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=video-build-your-first-desktop-application-with-flash-builder</link>
		<comments>http://www.jamesward.com/2010/04/01/video-build-your-first-desktop-application-with-flash-builder/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 13:47:35 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1667</guid>
		<description><![CDATA[In this video I walk through the basics of building Adobe AIR desktop applications in Flash Builder 4 using the Flex 4 SDK. Let me know what you think.]]></description>
			<content:encoded><![CDATA[<p>In this video I walk through the basics of building Adobe AIR desktop applications in Flash Builder 4 using the Flex 4 SDK.  Let me know what you think.</p>
<p><object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/IkWkZGLm-jo&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;hd=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IkWkZGLm-jo&#038;hl=en_US&#038;fs=1&#038;rel=0&#038;hd=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/04/01/video-build-your-first-desktop-application-with-flash-builder/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>Time to Update to Flex SDK 3.5a</title>
		<link>http://www.jamesward.com/2010/02/12/time-to-update-to-flex-sdk-3-5a/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=time-to-update-to-flex-sdk-3-5a</link>
		<comments>http://www.jamesward.com/2010/02/12/time-to-update-to-flex-sdk-3-5a/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 19:44:40 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[BlazeDS]]></category>
		<category><![CDATA[Flex]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/?p=1538</guid>
		<description><![CDATA[If you are using a Flex SDK before 3.5a then it&#8217;s probably time to update. Flex SDKs before 3.4 have a security vulnerability. I believe the problem is actually in the HTML template, so when you update make sure that you also update the HTML templates that you are using. The Flex SDK 3.4 had [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using a Flex SDK before 3.5a then it&#8217;s probably time to update.  Flex SDKs before 3.4 have a <a href="http://www.adobe.com/support/security/bulletins/apsb09-13.html">security vulnerability</a>.  I believe the problem is actually in the HTML template, so when you update make sure that you also update the HTML templates that you are using.  The Flex SDK 3.4 had the <a href="https://bugs.adobe.com/jira/browse/SDK-22883">double responder bug</a>.  And the initial release of Flex SDK 3.5 had a <a href="https://bugs.adobe.com/jira/browse/SDK-24766">bug with AIR&#8217;s ApplicationUpdaterUI</a>.  If you overlay your own AIR SDK on top of the Flex SDK then be aware that you will actually be overwriting the ApplicationUpdaterUI fix (comments in the bug report discuss how to deal with that).</p>
<p>So it&#8217;s time to move to the <a href="http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+3">latest Flex SDK 3.5a</a>!</p>
<p>Also, if you are using BlazeDS, LCDS, or FDS then it&#8217;s time to update that as well due to <a href="http://www.adobe.com/support/security/bulletins/apsb10-05.html">a security vulnerability</a> that was published yesterday.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2010/02/12/time-to-update-to-flex-sdk-3-5a/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Exciting Flash Platform Advancements</title>
		<link>http://www.jamesward.com/2009/12/16/exciting-flash-platform-advancements/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exciting-flash-platform-advancements</link>
		<comments>http://www.jamesward.com/2009/12/16/exciting-flash-platform-advancements/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 20:56:44 +0000</pubDate>
		<dc:creator>James Ward</dc:creator>
				<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[Flash Player]]></category>

		<guid isPermaLink="false">http://www.jamesward.com/blog/?p=1375</guid>
		<description><![CDATA[Recently there has been a number of exciting advancements with the Flash Platform (Flex, Flash Player, and Adobe AIR). Here is a quick round-up: Adobe released security updates for the Flash runtimes: Flash Player 10.0.42.34 and Adobe AIR 1.5.3. The Flash Player update fixes an issue with mouse scroll wheels not working in Flash when [...]]]></description>
			<content:encoded><![CDATA[<p>Recently there has been a number of exciting advancements with the Flash Platform (Flex, Flash Player, and Adobe AIR).  Here is a quick round-up:</p>
<p>Adobe released security updates for the Flash runtimes: <a href="http://www.adobe.com/go/gntray_dl_getflashplayer">Flash Player 10.0.42.34</a> and <a href="http://www.adobe.com/go/gntray_dl_getair">Adobe AIR 1.5.3</a>.  The Flash Player update fixes an issue with <a href="http://bugs.adobe.com/jira/browse/FP-503">mouse scroll wheels not working in Flash when using Safari</a>.</p>
<p>Recently, Adobe also released public betas for <a href="http://labs.adobe.com/technologies/air2/">Adobe AIR 2</a> and <a href="http://labs.adobe.com/downloads/flashplayer10.html">Flash Player 10.1</a>.  This Flash Player release fixes the &#8220;<a href="http://bugs.adobe.com/jira/browse/FP-40">Incorrect unicode input in Linux</a>&#8221; bug.  Both AIR 2 and Flash Player 10.1 have a new API for Global Exception Handling (which was <a href="http://bugs.adobe.com/jira/browse/FP-444">one of the highest rated feature requests</a> on <a href="http://bugs.adobe.com">bugs.adobe.com</a>).  Check out <a href="http://flex.org/tour">Tour de Flex</a> for some new samples on how to use this new and other new APIs.</p>
<p>For those looking to build Flex applications in the enterprise, Adobe has posted two great resources.  First is a <a href="http://www.adobe.com/products/player_census/flashplayer/enterprise_penetration.html">third-party study</a> that says <b>enterprise penetration of Flash Player 9 (or better) is at 97.6%!</b>  Second is a fantastic white paper about <a href="http://www.flashforbiz.com/Index.asp">The Business Benefits of Rich Internet Applications</a> &#8211; a must read for anyone in the enterprise who is evaluating Flex.</p>
<p>Last is a short video of me at Adobe MAX 2009 where I talk about the progress that Adobe is making in getting the Flash Platform onto the many screens in our lives and why that is exciting for developers.  Let me know what you think!<br />
<object width="425" height="256"><param name="movie" value="http://images.tv.adobe.com//swf/player.swf"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><param name="FlashVars" value="fileID=4141&#038;context=76&#038;embeded=true&#038;environment=production"></param><embed src="http://images.tv.adobe.com//swf/player.swf" flashvars="fileID=4141&#038;context=76&#038;embeded=true&#038;environment=production" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="256"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jamesward.com/2009/12/16/exciting-flash-platform-advancements/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

