Posts Tagged AS3

Donut Charts in AS3

Most of what I write comes from goals that I must achieve through my work and when I search the web to figure out how to do those I find very little information. So usually once I have figured it out I write a post about it. I was looking to create some donut charts which are basically pie charts but with a mask on them to make a hole in the middle. All I could find on the web was solutions that you had to pay for, bundles of charts that looked really bad. So I thought it shouldn’t be that bad to just to them from scratch.

Well I actually didn’t do them from scratch, first I translated some old ActionScript 2 found here to make the donut mask and I used Lee Brimelow wedge class to create the subdivision of the chart. So here are four examples of what you can do with it:

 

This movie requires Flash Player 9

 

And here is the code used to create them:

var wedgeVector:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector.push(new ChartWedgeInfo(0.3, 0x70ddff));
wedgeVector.push(new ChartWedgeInfo(0.21, 0x56baec));
wedgeVector.push(new ChartWedgeInfo(0.3, 0x2b78d2));
 
_donut1 = new DonutChart(50, 20, 0x1e457a, wedgeVector);
_donut1.x = 60;
_donut1.y = 60;
addChild(_donut1);
 
var wedgeVector2:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector2.push(new ChartWedgeInfo(0.5, 0xfca25a));
 
_donut2 = new DonutChart(40, 10, 0x821626, wedgeVector2);
_donut2.x = 180;
_donut2.y = 60;
addChild(_donut2);
 
_donut3 = new DonutChart(30, 25, 0x56baec);
_donut3.x = 300;
_donut3.y = 60;
addChild(_donut3);
 
var wedgeVector3:Vector.<ChartWedgeInfo> = new Vector.<ChartWedgeInfo>();
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xfca25a));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xfd8332));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xde4649));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0xaa2c34));
wedgeVector3.push(new ChartWedgeInfo(0.3, 0x821626));
 
_donut4 = new DonutChart(50, 30, 0x821626, wedgeVector3);
_donut4.x = 420;
_donut4.y = 60;
addChild(_donut4);

I think it is pretty easy to use. Here are some considerations; if you don’t give in any wedge info, it will just draw a donut, you can give more than 100% for your chart it will just loop, and the chart 0,0 is at the center of the donut. So here you go, you can just download the files below. I think it could be improved a little and there is no options to put labels or anything but it should fit more use cases that way.

DonutChartsSource

, , , ,

8 Comments


RTL languages and the Text Layout Framework

So this is the positive post about the Text Layout Framework that I was talking about earlier. For the current project I am working on I have the joy (read the sarcasm here) to be doing it in 9 languages and if that wasn’t fun enough one of those is Hebrew which is a right to left language. To be frank this kinda make the project really hard but not because of technical reasons, it makes it hard just to put the text at the right place… Anyway I digress, the thing when working with right to left languages is that there is not that much information on it or what you will find is really dated and not relevant anymore. Well it is that way with TLF in general too, so finding information on the subject is really tedious. Actually I didn’t find anything useful on the web and I had to figure things out on my own; that is why I am writing this post. Has I mentioned on the previous post, there are 3 ways to make text using the TLF: TLFTextfield, TextBlock or TextFlow. I will go through all of those and explain how to display RTL language correctly.

TLFTextfield

I find that this is the easiest way to display text using the Text Layout Framework. It is easy because it pretty much works the same as the good old Textfield. A colleague told me that the CSS part of it wasn’t really working and from the documentation it seems to be still in beta. To display a right to left language like Arabic, Hebrew or Persian, this seems like the way to go. Easily enough, it has a property called direction that you can just set to “rtl” and there you go, your text will display properly.

TextBlock

If you think you are going to be doing a version of your site/application for a RTL language, do not use TextBlock. That’s a shame cause this method of displaying text seems to give better looking text, but I was never able to get my Hebrew text displaying properly. It is weird because if you look at the documentation there seems to be a way to do it, using the bidiLevel property and setting it to an odd number (I have no idea why, this seems very unobvious to me). But I tried it and it doesn’t work. The problem arise when you have LTR text inside a RTL paragraph, so let’s say a english word inside a Arabic paragraph. This will greatly confuse the text engine and your text won’t display properly sometimes showing very differently than it the xml it has been taken from (if you pull your text from xml). So in this case, use TLFTextfield.

TextFlow

I am not a big fan of TextFlow, it seems more complicated for nothing, but I guess that if you want to display columns and more complex text that is the way to go. But has in the case of the TLFTextfield, it seems pretty easy to use RTL languages and TextFlow. So basically in your TextFlow markup you can do something like that <flow:p direction=”rtl”>my persian content</flow:p>. Easy enough, I haven’t tried it, but I have read that it works.

So there you have it, how I finally got it to work properly. Had I known before I would have built my site differently, I was using TextBlock everywhere, so now I check if the language is Hebrew and use TLFTextfield in that case. Also note that working with right to left text using tools that don’t really support it is really hard and confusing, the editor gets confused and selecting text becomes hell as it goes a bit for right then to the left and then right again. Be prepared for some trouble… Anyway I hope this saved some a bit.

, , , , , , , , ,

2 Comments


New Text Layout Framework, same font problems

I guess this has been said before, but I really feel like ranting. I will post a positive article later on about TLF, but for now I need to vent.

So I guess the problem come from the fact that I thought the new Text Layout Framework would solve all problems relating to fonts and Flash. But I guess that was hoping for too much. TLF does have a good side, it does make your text look better. I was skeptic at first, but it really does. The problem is, it has a lot of bad sides.

First problem is that it will add between 100k to 160k to your file size (pretty much forget about it for banners) and that is for every SWF that uses it. I don’t know about you but the sites I build usually contain at least 4 SWFs, so that’s nearly a megabyte just for the text engine, you’re not embedding the fonts yet or adding any content. There are ways to circumvent that but you still have to figure it out and it involves another workflow.

Secondly, there is not much documentation about it. I have been looking and it is pretty hard to figure out what is working or not. Seems like TLF changed since it was introduced, so some information is not relevant anymore. The other thing is that there are multiple ways to use it, you can use TextBlock and TextLine, you can use TLFTextField or you can use TextFlow. It gets pretty confusing at some point, cause you don’t solve the same problems the same ways with each of the three option I named before.

Lastly, it doesn’t work in every situation, I gave the banner example previously, but using the Text Layout Framework is also very expensive CPU wise. For example I was making this combobox which had an opened state with about a hundred items in it. Well it made the site become very slow. I was using TextLines and I had to revert to using good old TextFields. Which introduced a new problem, the font format that you use for TLF is not compatible with the old TextFields, so in this case I had to embed the same font twice, once DF3 and once DF4…

Which brings me to another point, which not necessarily negative, but the TLF does introduce new terminology and knowledge. WTF is DF3 or DF4 or embedCFF. So now your Flash baggage has to be bigger, what about when Molehill comes out, we will have to be interface experts, typography experts and 3D experts???

Well I promise next article will be positive.

, , , , , , , , , ,

2 Comments


Using the ActionScript 3 YouTube Api

On October 14th YouTube released a new version of it’s API for Flash. This version would support ActionScript 3. Previously discussed on here was the library TubeLoc which was basically an AS3 wrapper around the ActionScript 2 API. Now the new API does all TubeLoc pertmitted us to do and even more.

Well loading a YouTube video in ActionScript 3 has never been easier and there is nothing to download (which has its downside in some way)to get started.

Here is all the code needed to load a YouTube movie:

package {
 import flash.display.DisplayObject;
 import flash.display.Loader;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.net.URLRequest;
 
 public class Main extends Sprite {
  private var _loader : Loader;
  private var _player : Object;
 
  public function Main() { 
  _loader = new Loader();
  _loader.contentLoaderInfo.addEventListener(Event.INIT, _onLoaderInit, false, 0, true);
  _loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));
  }
 
  private function _onLoaderInit(event : Event) : void {
  _player = _loader.content; 
  _player.addEventListener("onReady", _onPlayerReady, false, 0, true);
  addChild (DisplayObject(_player));
 
  _loader.contentLoaderInfo.removeEventListener(Event.INIT, _onLoaderInit);
  _loader = null;
  }
 
  private function _onPlayerReady(event : Event) : void {
  _player.removeEventListener("onReady", _onPlayerReady);
  // Once this event has been dispatched by the player, we can use
  // cueVideoById, loadVideoById, cueVideoByUrl and loadVideoByUrl
  // to load a particular YouTube video.  
  _player.setSize(640, 360);
  _player.loadVideoById("D2gqThOfHu4");
  }
 }
}

You can compile this code as an ActionScript project or make it the Document class of an fla in the Flash IDE to make it work.

So you start by loading the player using a normal Loader. Once the player is loaded you have to wait for it to send the onReady event before you can interact with it. Once this is done you can call all of the function from the API.

The previous code would load the chromeless YouTube player; but if you wanted to use the controls from YouTube you would only have to replace one line:

//_loader.load(new URLRequest("http://www.youtube.com/apiplayer?version=3"));//replace this line with the following
_loader.load(new URLRequest("http://www.youtube.com/v/VIDEO_ID?version=3"));//replace VIDEO_ID with the id of the video you want to load in the previous case :"D2gqThOfHu4"
 
//also you can comment the following line if you don't want the video to start automatically:
_player.loadVideoById("D2gqThOfHu4");

All the functionalities that where accessible with TubeLoc are also accessible with the AS3 API and there are some more. Those are methods to control the quality setting of the loaded movie. You can set the quality to small, medium, large and hd720. To do so you have 3 methods on the player. getPlaybackQuality():String will return the quality of the video currently playing. setPlaybackQuality(suggestedQuality:String) enables you to set the quality. Finally, getAvailableQualityLevels():Array will return you all the possibilities of quality that you can set the current video to.

For more information on the topic, refer to the API : http://code.google.com/apis/youtube/flash_api_reference.html

, , , , ,

14 Comments


Fonts are my bane; not anymore!

I hate managing fonts in Flash, I truly hate it. I don’t understand why it is not easier than this after all that time. How about underline; why can’t we still underline in the Flash IDE? That shouldn’t be voodoo magic, even Notepad has underline, ok, Notepad doesn’t have the underlining functionality, but Wordpad does.

Anyway, my biggest problem with fonts and Flash is not the underlining problem, but when you start using static and dynamic textfields with the same font family but with different font style. When you do that, your dynamic textfields will just not show and that is really annoying. A solution that works is if you put all textfields dynamic, but that’s even more annoying.

Now a really cool feature is that you can now embed fonts using the embed tag just like this:

[Embed(source="assets/fonts/GNL_____.PFB", fontName ="zedia GillSansLight", unicodeRange='U+0020-U+007A, U+00C0-U+00F6, U+2019', mimeType="application/x-font-truetype")]
private var GillSansLight2:Class;

Not sure that this will work when you compile using the Flash IDE, but when doing ActionScript projects or Flex projects this works just fine. This way you can embed ttf, otf and pfb fonts. I am not quite sure how to embed fonts on a Mac system, it will still work with those formats, but I know Macintosh has other formats. The thing that makes this work is that you can specify the font name. Be sure to specify a name that you know Flash wouldn’t specify. My coworker gave me the trick to add the name of the project in the font name that way it’s always going to be different than Flash. If you don’t make it different you will still run in the problem of your dynamic textfields not showing up.

Once you have embedded the font you need to register it in your application like this:

Font.registerFont(GillSansLight2);

This will make the font available anywhere in your application. All you need to do is create a TextFormat with that font and assign that TextFormat to your textfield:

var tf:TextFormat = new TextFormat("zedia GillSansLight");//this is what you put into fontName in the embed tag
myTextfield.embedFonts = true; //this line is also important
myTextfield.defaultTextFormat = tf; //always assign the default textformat before modifying the text property
myTextfiled.text = "lorem ipsum";

Now, using this technique you can choose exactly what character from the font you want to embed. In the previous example the unicodeRange represented those characters:

U+0020-U+007A = SPACE!"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz
U+00C0-U+00F6 = ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö
U+2019 = ’

This is a pretty safe set, but you can always change it and optimize it.

Here is a good resource to do Unicode conversion:
http://rishida.net/scripts/uniview/conversion.php

, , , , , , , ,

12 Comments


How to load a YouTube movie into Flash using TubeLoc

I have written this article a while back for FFDMag, but I thought I would put it here also. It lost a bit of relevance because YouTube now has an AS3 API for its player, but if you work on a project that uses TubeLoc, I think this article can be useful.

What you should know:
- Basic knowledge of ActionScript
- Basic knowledge of YouTube

What you will learn:
- How to load YouTube videos into Flash
- How to use the TubeLoc library to control those videos

Embedding a YouTube movie in an HTML page is an easy task, but we can’t say the same about embedding a YouTube clip in a Flash/Flex website. TubeLoc, an opensource library, is there to make that easier.

Before TubeLoc, you could always go and try to find the address of the FLV the YouTube player is loading and load that FLV directly into your Flash application, but YouTube changes the address almost every night, so it wasn’t a very long term solution. Another problem that TubeLoc solves is the fact that the YouTube player is made in ActionScript 2 and most projects now are using ActionScript 3, so it was hard interfacing with the player. TubeLoc is a wrapper around the the AS2 player and show us an AS3 API, but behind the scene it handles the YouTube player using local connection.

To get started with TubeLoc you will first need to download the library at this address:

http://code.google.com/p/tubeloc/

There you will also find a great demo showing you what you can do with the library. You can pause, stop, play, mute, seek, change the volume, change the the size of the video and even load the video without the YouTube player chrome (so you won’t see the play button from YouTube the only thing that will be there is the YouTube logo at the bottom right of the video).

In the zip file that you download from the previous url, copy the “com” folder located in the “as3/src” folder in the same directory where your FLA will be. Also copy there the file as2_tubeloc.swf from the folder “as3/lib”. Now we can get coding. Here is all that is needed to load a YouTube movie into Flash:

import com.enefekt.tubeloc.MovieSprite;
import com.enefekt.tubeloc.event.*;
 
var youtubeMovie:MovieSprite = new MovieSprite(null, true);
youtubeMovie.addEventListener(PlayerReadyEvent.PLAYER_READY, onPlayerReady);
addChild(youtubeMovie);
 
function onPlayerReady(event_p:PlayerReadyEvent):void {
//it's just cleaner to remove listener that won't be used again
youtubeMovie.removeEventListener(PlayerReadyEvent.PLAYER_READY, onPlayerReady);
 
//you can set the size of the movie this way
youtubeMovie.width = 370;
youtubeMovie.height = 276;
 
youtubeMovie.loadVideoById("tprMEs-zfQA");
}

The first lines import the library from the “com” folder we copied. After that it creates the MovieSprite. The first parameter is the id of the YouTube movie, since I will set that later I can just pass null to it. The second parameter is if I want to use the chromeless player, in this case I set it to true. The chromeless player is usefull when you want the video player to have control that are similar to the rest of your application. It is also usefull when you want to put your video under a mask to escape the traditonnal square look of videos. If we continue with the code, after we created the MovieSprite, we have to wait for the player to be initialized to go on that’s why we put an event listener on the MovieSprite(youtubeMovie). Once the listener function is called, all that is left to do is call the loadVideoById method. Finding a video id from YouTube is really easy; if the url of the video you want to load looks like this:

http://www.youtube.com/watch?v=tprMEs-zfQA

Than your id is only the last part : “tprMEs-zfQA”.

Now if you want to control your video all you have to do is :

//this will pause the video
youtubeMovie.pauseVideo()
 
//this will make it play again
youtubeMovie.playVideo()
 
//to mute the video
youtubeMovie.mute()
 
//to set the volume to half of maximum
youtubeMovie.setVolume(50)
 
//to seek in the video to 20 seconds
youtubeMovie.seekTo(20)

Well that is all it take to load a YouTube movie into Flash. I should warn you of some pitfalls; by reading the issues on the google code page, there seems to be problems with loading multiple videos at the same time. Also, destroying an instance of a MovieSprite seems to inhibit you from creating another one after so you should always keep an instance of you MovieSprite alive. Aside from that TubeLoc is an awesome library and I hope to see the proliferation of YouTube videos inside of Flash!

, , , , ,

13 Comments


Introduction to TimelineLite / TimelineMax

TimelineLite is a new library from the maker of TweenLite that enables you to group TweenLite instances (Tweens) to create the equivalent of the Flash Authoring Tool Timeline but in code. If you don’t know what TweenLite is head over to my tutorial on it first.

What is it for

The goal of this library is to give more power to the already powerful TweenLite library and to emulate some of the MovieClip’s functionalities. Once built, a TimelineLite instance will possess some methods that we’ve known for a long time: play(), stop(), gotoAndPlay(), etc. Three methods are used to create the timeline: append(), insert(), insertMultipple(). I prefer the insert method, it gives you more flexibility because you can set the time at which the Tween starts. The append() method will simply add your TweenLite instance at the end of the current timeline.

Here are some examples of how you would create a TimelineLite :

var myTimeline:TimelineLite = new TimelineLite();
 
//this will have 3 tween starting one after the one before is done
myTimeline.append(new TweenLite(mc, 1, {x:200, y:100}));
myTimeline.append(new TweenLite(mc, 0.5, {alpha:0}));
myTimeline.append(new TweenLite(mc, 0.5, {alpha:1}));
 
myTimeline.play();
 
//this one will have concurrent tweens a bit like layered tweens in the Flash Timeline
myTimeline.insert(new TweenLite(mc, 1, {x:200, y:100}), 0);
myTimeline.insert(new TweenLite(mc, 0.5, {alpha:0}), 0.75);
myTimeline.insert(new TweenLite(mc, 0.5, {scaleX:2}), 1.25);

Some of the cool stuff you can do with is that inside a TimelineLite you can insert other TimelineLite instances. Also you can add Labels and tween using TweenLite to those labels. You can tween the time of the timeline as well as the progress. Here are examples of what I just mentioned:

var myTimeline:TimelineLite = new TimelineLite();
myTimeline.insert(new TweenLite(mc, 1, {x:200, y:100}), 0);
myTimeline.insert(new TweenLite(mc, 0.5, {alpha:0}), 0.75);
myTimeline.insert(new TweenLite(mc, 0.5, {scaleX:2}), 1);
 
//Tween the timeline to any place in percent (from 0 to 1)
TweenLite.to(myTimeline, 0.5, {progress:1});
 
//Tween to a particular second in time (from 0 to the duration of the timeline)
TweenLite.to(myTimeline, 0.5, {time:0.75});

Its advantages

The major advantage that TimelineLite posesses over real timeline is the fact that it is dynamic. Meaning that you could make an function that takes a display object, that function would create an animation based on it and return a TimelineLite instance that you could use afterward. Then you could use that function to create the same animation on multiple display objects. Another example is that you could create animation based on what the user does, like you make him choose a number and you append that many instances on TweenLite in your TimelineLite (easy to do with traditionnal timeline too, but its just an example).

Its Max conterpart

As for the TweenLite library, TimelineLite has its Max equivalent, TimelineMax, which has more features like AS3 event listeners, repeat, repeatDelay, yoyo, addCallback(), removeCallback(), getActive(), etc.  Just to tell you how good this library is,  I have done a TimelineLite instance that tweened 25 display objects and 625 TweenLite instances and it worked perfectly fine, it wasn’t even slowing down.

, , , , , ,

4 Comments


How to connect to Google Analytics Data API in Flash

In one of my previous post, I explained how to connect to Google Analytics Data API in AIR. The problem with that way of connecting was that it only worked in AIR. In Flash it works locally, but as soon as you put in on your web server it stops working. Not it is cool to build an AIR (desktop) application that pulls data from Google Analytics, but it would also be cool to build a web application that does the same thing. Well I found out how to do just that. It is a bit more complicated because it involves a bit of server side coding, in this case PHP.

How the process works is that first you login to Google Analytics, Google will then send you a token that you must use when asking for data. So we will have two simple PHP files; one to login in and one to ask for data.

The first one looks like this:

<?php
//this file is called get_token.php
$user = $_REQUEST[user];
$pass = $_REQUEST[pass]
 
require_once 'curl.php';
$curl = new Curl;
$response = $curl-&gt;post('https://www.google.com/accounts/ClientLogin', array(accountType => "GOOGLE",  Email =>$user, Passwd => $pass, service => "analytics", source => "zedia-GAStats-0" ));
$tempArray = explode("Auth=", $response);
?>
<root>
	<token><?php echo ($tempArray[1] ); ?></token>
</root>

The second one looks like this:

<?php
//this file is called call_ga.php
require_once 'curl.php';
$url = $_REQUEST["url"];
$token = $_REQUEST["token"];
 
$curl2 = curl_init();
curl_setopt($curl2, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl2, CURLOPT_HEADER, "0");
curl_setopt($curl2, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl2, CURLOPT_URL, $url);
 
curl_setopt($curl2, CURLOPT_HTTPHEADER, array('Authorization: GoogleLogin auth=' . $token));
$response2 = curl_exec($curl2);
echo ($response2);
?>

As you can see to make my calls to Google I am using the cURL library that is usually already installed on your server if you have PHP. Also for the get_token.php I am also using the Curl class, made by Sean Huber, that just makes it easier to work with cURL.  Upload these files to your server. Now that we have the server side figured out, we can move on to the Flash part;  here it is:

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.text.TextField;
 
public class Main extends Sprite
{
  private var loader:URLLoader;
  private var _loader2:URLLoader;
  private var _textField:TextField;
  private var _token:String;
  private var _buffer:String = "";
  public function Main():void
  {
    loader = new URLLoader();
    loader.addEventListener(Event.COMPLETE, _onTokenLoaded, false, 0, true);
   //this call will load the token
 
    loader.load(new URLRequest("http://www.YOUR_URL_WHERE_THE_PHP_RESIDE.net/get_token.php?user=YOUR_USERNAME&pass=YOUR_PASSWORD"));
 
    _textField = new TextField();
    _textField.height = 300;
    _textField.width = 300;
    _textField.multiline = true;
    _textField.wordWrap = true;
 
    addChild(_textField);
  }
 
  private function _onTokenLoaded(event:Event):void {
    var tempString:String = String(loader.data);
    tempString = tempString.substring(1, tempString.length);
    var tempXML:XML = XML(tempString);
    _token = tempXML.token;
 
    _textField.text = _token;
 
    _loader2 = new URLLoader();
    _loader2.addEventListener(Event.COMPLETE, _onFeedLoaded, false, 0, true);
 
    var request:URLRequest = new URLRequest("http://www.YOUR_URL_WHERE_THE_PHP_RESIDE.net/call_ga.php");
    var urlVar:URLVariables = new URLVariables();
    urlVar.token = _token;
    urlVar.url = "https://www.google.com/analytics/feeds/accounts/default";
    request.data = urlVar;
 
    _loader2.load(request);
  }
 
  private function _onFeedLoaded(event:Event):void {
    _textField.text = String (_loader2.data);
  }
 }
}

What you basically do is that you use your server to do all the communication between the Flash and Google. Everytime you will want a different feed to get different data you will call the call_ga.php file. It is that simple. If you have any question on this feel free to ask them in the comments.

, , , , , ,

12 Comments


How to connect to Google Analytics Data API in AIR

I had a bit of trouble doing just this a while ago, ended up trying many different ways and finally a reader of this blog, Nakamachi, gave me the solution. Because I think many of you are trying to connect to Google Analytics Data API ( or any Google APIs for that matters) I will give you here my solution. My solution only works in AIR; I don’t know why, but as soon as I put it on the web, it stops working. I have found a solution for that problem too but I will keep it for another post.
Here is how you can connect to GData:

import org.httpclient.HttpClient;
import com.adobe.net.URI;
import org.httpclient.events.HttpResponseEvent;
import org.httpclient.events.HttpRequestEvent;
import org.httpclient.HttpRequest;
import org.httpclient.http.Get;
import org.httpclient.events.HttpDataEvent;
 
var _firstBuffer:String = "";
var _secondBuffer:String = "";
 
//this first connection will get the authorization token by sending the user name and password for Google Analytics
function submitForm(email:String, password:String):void {
  var client:HttpClient = new HttpClient();
  var uri:URI = new URI("https://www.google.com/accounts/ClientLogin");
  var variables:Array = [{name:"accountType", value:"GOOGLE"}, {name:"Email", value: email}, {name:"Passwd", value: password}, {name:"service", value: "analytics"}, {name:"source", value: "your-application-identifier"}];
  client.listener.onData = _onFirstData;
  client.listener.onComplete = _onLoaderComplete;
  client.postFormData(uri, variables);
}
 
function _onFirstData(event:HttpDataEvent):void {
  _firstBuffer += event.readUTFBytes();
}
 
//this second connection will request information to GData
//in this case account info for Google Analytics by
//putting the auth token in the header of the request
function _onLoaderComplete(event:HttpResponseEvent):void {
  var tempArray:Array = _firstBuffer.split("Auth=");
 var  _authToken:String = String(tempArray[1]);
 
  var client:HttpClient = new HttpClient();
  var uri:URI = new URI("https://www.google.com/analytics/feeds/accounts/default");
  var request:HttpRequest = new Get();
  request.addHeader("Authorization", "GoogleLogin auth=" + _authToken);
 
  client.listener.onData = function(event:HttpDataEvent):void {
    _secondBuffer += event.readUTFBytes();
  }
  client.listener.onComplete = _onSecondLoaderComplete;
  client.request(uri, request);
}
 
function _onSecondLoaderComplete(event:HttpResponseEvent):void {
  trace (_secondBuffer);
}

As you can see in order to circumvent the Authorization header restriction I am using the as3httpclientlib library which requires the as3corelib and as3crypto libraries to compile. Using the same principle you should be able to connect to Google APIs from your AIR application.

, , , , , , , ,

14 Comments