background

Posts Tagged ‘air’

Video Chat for Android in 30 Lines of Code

Posted in Shared on July 23rd, 2010 by herkulano – Be the first to comment

Here is a simple Video Chat application I built with Flex 4 and deployed on AIR for Android. The Application is just 30 lines of code and allows multiple users to join a chat room and “video chat”.

Video streaming is powered by LiveCycle Collaboration Services, a set of hosted Flash Services that enable developers to easily add real-time collaboration and social capabilities to their applications.

This application is obviously a bare-bones proof of concept. However, it is fully operational, and the same code can run on different runtime environments: AIR for Android, AIR on the Desktop, and Flash Player in the Browser. Users can participate in the same collaboration session regardless of the runtime environment they use.

Watch the video:

The 30 lines of code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:cs="AfcsNameSpace" currentState="logon" fontSize="28">

	<fx:Script>
		[Bindable] private var roomURL:String = "http://connectnow.acrobat.com/YOUR_ROOM_NAME";

		protected function connect():void {
			auth.userName = userName.text;
			currentState = "default";
			session.login();
		}
	</fx:Script>

	<s:states>
		<s:State name="default"/>
		<s:State name="logon"/>
	</s:states>

	<fx:Declarations>
		<cs:AdobeHSAuthenticator id="auth"/>
	</fx:Declarations>

	<s:TextInput id="userName" includeIn="logon" top="200" horizontalCenter="0"/>
	<s:Button label="Connect" click="connect()" includeIn="logon" top="250" horizontalCenter="0" height="50" width="150"/>

	<cs:ConnectSessionContainer id="session" roomURL="{roomURL}" authenticator="{auth}" autoLogin="false" width="100%" height="100%" includeIn="default">
		<cs:WebCamera top="10" left="10" bottom="10" right="10"/>
	</cs:ConnectSessionContainer>

</s:Application>

Monetize your AIR applications with Melrose

Posted in Shared on July 22nd, 2010 by herkulano – Be the first to comment

Melrose – the monetization service previously known as Shibuya – is now live on Adobe Labs.

If you were at MAX last year you probably remember the demo I did in the keynote on day 2. With literally just a couple lines of code you can add a complete license manager and payment solution to your AIR application. You can even create time and feature based trials.

Melrose works exactly like all the other application stores out there. We don’t charge any monthly or yearly fees but we do take a percentage of your earnings (obviously there is no charge for free apps). In return we’ll provide a safe and secure way to monetize your AIR applications. That means you don’t have to worry about things like credit card processing and hosting your license manager logic. Your private dashboard will tell you how your application is doing. You can view charts on number of downloads of your apps, number of trials, number of purchases, revenue, number of activations, and trial to purchase histogram (i.e. conversions from trials to purchases).

Developers and publishers in 47 countries can use Melrose to distribute and monetize AIR applications.

Melrose is still in private beta but you can already sign up today. You can find all the necessary info on the Melrose Labs page.

Some Flash Android Components

Posted in Shared on May 28th, 2010 by herkulano – Be the first to comment

You have those times when you get an idea, so you sit down and start building it? You know, maybe you are a designer, and that means cracking up Flash Pro CS5. Or perhaps you are a developer and you start messing with item renderers. As I travel around from conference to conference, I get a lot of ideas like that. And for most of them, I either run out of steam, get distracted, or simply get bored. Over the next several weeks I’ll be dropping projects like that on the old blog – starting with these Flash components that look like Android.

I wanted to get to know Android – intimately. So I started examining the user interface controls. At first this was mostly on the device, to get a feel for the types of controls that were available, and the way they transitioned states. Next I started using the “ddms” screen capture utility that comes with the Android SDK to get a closer look at the pixels. I’d get the screen to a state I wanted, capture it, and then dissect it using Fireworks CS5. Finally, I started reassembling the controls in Flash Pro CS5 and putting ActionScript logic behind them.

The result is a pretty performant, and decent foundation of controls that look and feel like Android, but are done all with Flash, and expected to be deployed using AIR for Android. I could go a lot further with these, but then again, there’s that running out of steam thing. For example, these are really designed for the NexusOne – I don’t account for screen density. I also don’t account for screen orientation, though there’s hooks in the components for some basic sizing.

Okay, enough about what’s not there, what is there?

  • Button
  • CheckBox
  • ComboBox
  • DateChooser
  • Footer
  • Label
  • List
  • Menu
  • NumericStepper
  • TextInput
  • TimeChooser
  • Title

Some of these components need additional explanation. For example, the “DateChooser”. Most of the dates in Android are presented via a modal dialog box. Mine is no different. Though I don’t call them out as components in the above list, there’s stepper controls used by the dialog to control month, date and year. Likewise for the “TimeChooser” where you will find controls for the hour and minute.

“Footer” is the bar you find at the bottom of most Android forms. The Footer control accepts up to three strings, that will give you up to three buttons. Why three? Well, because that’s the most I saw in use on any Android application. The “Title” is the gray bar you see at the top of most Android forms. The “Menu” takes up to six buttons, and shows up at the bottom of the screen when you use the hard menu button on the device.

Regardless of the component, they are designed to be pretty atomic, and although they were designed in Flash Pro CS5, then can easily be used in Flash Builder 4 from an ActionScript project, because I include a SWC in the build. Here’s some example code, and the result user interface. In short, you instantiate the control you want, position it and size it if necessary, and then add it to the stage. Register for any events you may want to drive the rest of the application at runtime.

package  
{
  import flash.display.Sprite;
  import flash.display.StageScaleMode;
  import flash.display.StageAlign;
  import flash.events.MouseEvent;
 
  public class Components extends Sprite 
  {
    private var btn:Button = null;
    private var chk:CheckBox = null;
    private var cmb:ComboBox = null;
    private var day:DatePicker = null;
    private var ftr:Footer = null;
    private var lbl:Label = null;
    private var listing:ListPicker = null;
    private var opt:OptionPicker = null;
    private var time:TimePicker = null;
    private var mnu:Menu = null;
    private var tme:Button = null;
    private var ttl:Title = null;
    private var txt:TextInput = null;
 
    public function Components() 
    {
      super();
      init();
    }
 
    private function init():void
    {
      var btnx:Button = null;
      var lblx:Label = null;
      var today:String = DateDialog.formatShort( new Date() );
 
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
 
      ttl = new Title( "Event details" );
      addChild( ttl );
 
      lbl = new Label( "What" );
      lbl.x = 9;
      lbl.y = 52;
      addChild( lbl );
 
      txt = new TextInput( "Event name" );
      txt.x = 9;
      txt.y = 85;
      addChild( txt );
 
      lblx = new Label( "From" );
      lblx.x = 9;
      lblx.y = 170;
      addChild( lblx );
 
      btn = new Button( today, 282, Button.TRIGGER );
      btn.x = 14;
      btn.y = 203;
      btn.addEventListener( MouseEvent.CLICK, doDateClick );
      addChild( btn );
 
      tme = new Button( "1:00pm", 158, Button.TRIGGER );
      tme.x = 306;
      tme.y = 203;
      tme.addEventListener( MouseEvent.CLICK, doTimeClick );
      addChild( tme );			
 
      lblx = new Label( "To" );
      lblx.x = 9;
      lblx.y = 276;
      addChild( lblx );
 
      btnx = new Button( today, 282, Button.TRIGGER );
      btnx.x = 14;
      btnx.y = 309;
      addChild( btnx );
 
      btnx = new Button( "2:00pm", 158, Button.TRIGGER );
      btnx.name = "to";
      btnx.x = 306;
      btnx.y = 309;
      addChild( btnx );			
 
      chk = new CheckBox();
      chk.x = 416;
      chk.y = 396;
      chk.addEventListener( MouseEvent.CLICK, doCheckClick );
      addChild( chk );
 
      cmb = new ComboBox( "Home" );
      cmb.x = 13;
      cmb.y = 487;
      cmb.addEventListener( MouseEvent.CLICK, doComboClick );
      addChild( cmb );
 
      ftr = new Footer( "Done", "Revert" );
      ftr.y = 680;
      addChild( ftr );
 
      mnu = new Menu( [
        {path: "search.png", label: "One"},
        {path: "search.png", label: "Two"},
        {path: "search.png", label: "Three"},
        {path: "search.png", label: "Four"},
        {path: "search.png", label: "Five"},
        {path: "search.png", label: "Six"}
      ] );
      mnu.addEventListener( MenuEvent.CLICK, doMenuClick );
      addChild( mnu );
 
      day = new DatePicker();
      day.addEventListener( DialogEvent.OK, doDateOk );
      day.addEventListener( DialogEvent.CANCEL, doDialogCancel );
      addChild( day );
 
      time = new TimePicker();
      time.addEventListener( DialogEvent.OK, doTimeOk );
      time.addEventListener( DialogEvent.CANCEL, doDialogCancel );
      addChild( time );			
 
      listing = new ListPicker();
      listing.addEventListener( ListEvent.CLICK, doListingClick );
      addChild( listing );
    }
 
    protected function doCheckClick( event:MouseEvent ):void
    {
      var btnx:Button = null;
 
      if( chk.selected )
      {
        tme.visible = false;
        btn.setWidth( 450 );
      } else {
        tme.visible = true;
        btn.setWidth( 282 );				
      }
    }
 
    protected function doComboClick( event:MouseEvent ):void
    {
      listing.show( [
        "Default ringtone", "Backroad", "Bell Phone", "Big Easy",
        "Bird Loop", "Bollywood", "Bus' a Move", "Cairo",
        "Calypso Steel", "Champagne Edition", "Chimey Phone",
        "Club Cubano", "Crayon Rock", "Curve Ball Blend", "Dancin Fool",
        "Digital Phone", "Ding", "Don' Mess Wiv It", "Eastern Sky",
        "Enter the Nexus", "Ether Shake", "Flutey Phone", "Free Flight",
        "Funk Y'all", "Gimme Mo' Town", "Glacial Groove", "Growl",
        "Halfway Home", "Loopy Lounge", "Los Angeles, 2019", 
        "Love FLute", "Medieval Jaunt", "Mildly Alarming", "Nairobi",
        "Nassau", "No Limits", "Organ Dub", "Paradise Island", "Playa",
        "Radiation by Spagnola", "Road Trip", "Safari", "Seville", 
        "She's All That", "Silky Way", "Steppin' Out", "Terminated",
        "Third Eye", "Twirl Away", "World"], 
        "Ringtones" 
      );
    }
 
    protected function doDialogCancel( event:DialogEvent ):void
    {
      trace( "Dialog cancel." );
    }
 
    protected function doDateClick( event:MouseEvent ):void
    {
      day.show( new Date() );
    }
 
    protected function doDateOk( event:DialogEvent ):void
    {
      btn.label = DateDialog.formatShort( day.date );
    }
 
    protected function doListingClick( event:ListEvent ):void
    {
      cmb.label = event.label;
    }
 
    protected function doMenuClick( event:MenuEvent ):void
    {
      trace( event.label );
    }
 
    protected function doTimeClick( event:MouseEvent ):void
    {
      time.show( new Date() );
    }
 
    protected function doTimeOk( event:DialogEvent ):void
    {
      tme.label = TimeDialog.formatShort( time.time );
    }		
  }
}

main_screentext_input

date_dialogtime_dialog

combo_dialogdevice_menu

Again, I want to note that this is a random idea project. It’s pretty modular, but may not be to the liking of many. The package structure is totally flat, though I suppose that’s a nit-pick more than a problem. If you are thinking that I should have skinned Keith Peters’ Minimal Comps, you’re probably right, but I started this on a plane, and it grew from there before Keith’s components could be skinned. All of it is available for download. If you find it useful, or have any questions about the architecture, don’t hesitate to ask.

Mobile Enterprise Sample Applications Powered by Adobe AIR, Flex and Android

Posted in Shared on May 25th, 2010 by herkulano – Be the first to comment

Last week at the Google I/O conference, we announced the public availability of the Adobe AIR for Android Developer Prerelease program. This week, we wanted to highlight a few excellent examples of AIR and Android powered enterprise applications developed by two members of our evangelism team, Christophe Coenraets and James Ward.

Both Christophe and James recently recorded inspiring video demonstrations of some of the sample applications they have been working on lately.

Mobile version of Employee Directory application by Christophe Coenraets.

Trading sample application by Christophe Coenraets.

Example of a Flex and AIR application that includes multi-touch support by James Ward.

One Application, Five Screens (Including the iPad)

Posted in Shared on April 3rd, 2010 by herkulano – Be the first to comment

This morning, I was able to validate a concept I've been working on for a couple of weeks now: running one application — completely unchanged — on five different screens:

  • iPad
  • iPhone/iPod touch
  • Motorola Droid
  • Desktop (Mac, Windows, and Linux)
  • Browser

The application is called iReverse, and it's is a fully functional Reversi game (complete with a pretty decent AI). Although iReverse is fun to play, the most amazing thing about the project is the fact that it runs in all these different environments completely unchanged. In other words, the exact same code base is used to build versions for five different environments. There's no other platform in the world that can boast this level of flexibility — not even close.

All of these versions are running on AIR technology except for the browser version, but since I didn't use any AIR-specific APIs (game persistence is done through Local Shared Objects rather than files), it runs entirely unchanged in the browser, as well.

Check out the video and screenshots for more information. In the next couple of weeks, I plan to release all the code for iReverse, and an article describing everything I learned about writing a truly multi-screen application.




iPad in Landscape

iPad in Portrait

iPhone in Landscape

iPhone in Portrait

Android in Landscape

Android in Portrait

Desktop in Landscape

Desktop in Portrait

Browser in Landscape

Browser in Portrait

A glimpse into the project architecture I used for iReverse

AS3 Library for OAuth with Twitter for AIR Apps

Posted in Shared on July 8th, 2009 by herkulano – 2 Comments

AIR is very popular for creating twitter clients, Sönke Rohde just made it much easier to make AIR apps for twitter with an AS3 library for Twitter. This library is built on top of core oauth as3 library by iotashan.  Core OAuth as3 library is a standard OAuth library this can be used for your own OAuth backends or connecting to other OAuth services as well.

A very nice feature of this library, in addition to being coded cleanly and as3 style, is the ability to have the Twitter OAuth page render inside of Flash.

Instead of opening the Twitter authorization page in the browser the library also contains OAuthLoader which is a wrapper around HTMLLoader which enables to directly show the authorization page within an AIR window:

// use this in the requestTokenHandler instead of navigateToURL
var loader:OAuthLoader = new OAuthLoader();
loader.load(request);
loader.percentWidth = 100;
loader.percentHeight = 100;
var w:Window = new Window();
w.width = 800;
w.height = 400;
w.title = req.url;
w.addChild(loader);
w.open();

Adobe AIR driving the military of tomorrow

Posted in Shared on June 2nd, 2009 by herkulano – Be the first to comment
Last week I blogged about how Flash and AIR are used in the motion picture industry. This week I wanted to talk about another fascinating use of Adobe AIR. Wade Arnold and his company T8DESIGN built an AIR interface for the US military that is used to drive a cutting edge combat robot call the R-Gator. You all know Wade as the developer of AMFPHP and now the Zend AMF framework. Well in his real job he is building things that are helping to save the lives of our troops. The R-Gator is essentially an unmanned vehicle that is driven remotely using an XBOX 360 controller of all things.

Wade talked to me a bit about the scenarios about how these are being used in the field. The R-Gator can be used as an unmanned recon scout or continuose perimeter base defense. Troops will also send the robot into hostile areas and make it appear as if it is being driven by actual troops. The vehicle can also be equipped with REDOWL, or Robot Enhanced Detection Outpost with Lasers, that can detect and locate snipers and mortars on the very first shot fired at personnel or vehicles. The operator can then provide a measured response using a 50 caliber machine gun that is mounted on the back. The R-Gator can also be equipped with a thermal laser to light up targets for air strikes. This keeps troops out of harms way while the R-Gator takes all the risks. Click on the images below to see some screenshots of the interface.

Wade also mentioned how the XBOX controller is preferred as young troops are accustomed to it which I thought was pretty funny. For obvious reasons I can’t go into a lot of details about the underlying technology but it is essentially an Adobe AIR front-end that streams live video using FMS. It has a Linux operating system and there was quite a bit of custom work that T8 had to do to get it running. The R-Gator was created by John Deere and represents the cutting edge of today’s military.

Lee

Merapi Now Open Source

Posted in Shared on May 20th, 2009 by herkulano – Be the first to comment
I am in Adam Flater’s session on Merapi at 360Flex and he has announced that Merapi is now open source. What is Merapi? Merapi allows developers to connect Adobe AIR applications, written in Adobe Flex to connect to Java applications running on the user’s local computer. Where can I get Merapi? http://code.google.com/p/merapi/ What about examples? http://code.google.com/p/merapi-examples/ Merapi Group: http://groups.google.com/group/merapi-project So go get it [...]