blog

Authorizing Facebook Applications in Android at Jozef Chúťka's blog

October 13, 2010

No comments

AIR Android Facebook FacebookOAuthGraph StageWebView

Authorizing Facebook Applications in Android

Hold on, this is going to be fast and smooth! I am playing with an Android Emluator for a few days now. One of the challenges was to mount FacebookOAuthGraph lib into Android. It turned out to be 1 hour task. Thanks to Flash-Core article and sHTiF and StageWebView. Long live AIR for Android! 🙂 Follow the article for codes:

You do not need a callback.html file, as in previous AIR example, you can use non existing redirect_uri targeting correct domain + a simple extending of FacebookOAuthGraph:

package
{
    import flash.display.Stage;
    import flash.events.LocationChangeEvent;
    import flash.geom.Rectangle;
    import flash.media.StageWebView;
    
    import onboard.Controller;
    
    public class FacebookAndroid extends FacebookOAuthGraph
    {
        public var loader:StageWebView;
        public var stage:Stage; // this is the air application Stage
        
        public function FacebookAndroid()
        {
            super();
        }
        
        override public function connect():void
        {
            var bounds:Rectangle = new Rectangle(0,0,480,480);
            
            loader = new StageWebView();
            loader.addEventListener(LocationChangeEvent.LOCATION_CHANGING, onLocationChanging);
            loader.addEventListener(LocationChangeEvent.LOCATION_CHANGE, onLocationChange);
            loader.stage = stage;
            loader.viewPort = bounds;
            loader.loadURL(authorizationURL);
        }
        
        private function onLocationChanging(event:LocationChangeEvent):void
        {
            event.preventDefault();
            loader.loadURL(event.location);
        }
        
        private function onLocationChange(event:LocationChangeEvent):void
        {
            var hash:String = locationExtractHash(loader.location);
            var error:String = locationExtractError(loader.location);
            if(hash)
                confirmConnection(hash);
            if(hash || error)
                destroyLoader();
        }
        
        protected function locationExtractHash(url:String):String
        {
            var index:int = url.indexOf("#");
            if(index <= -1)
                return null;
            var hash:String = url.substr(index + 1);
            return hashToToken(hash) ? hash : null;
        }
        
        protected function locationExtractError(url:String):String
        {
            var index:int = url.indexOf("?");
            if(index <= -1)
                return null;
            var query:String = url.substr(index + 1);
            var variables:URLVariables = new URLVariables(query);
            return variables.hasOwnProperty("error") ? variables.error : null;
        }

        private function destroyLoader():void
        {
            loader.removeEventListener(LocationChangeEvent.LOCATION_CHANGING, onLocationChanging);
            loader.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, onLocationChange);
            loader.dispose();
            loader = null;
        }
    }
}

How does this works? You do not need any callback.html, just generate some redirect_uri that correctly targets your domain, it can be anything, even 404.html, or asdf-foo-bar.html file that does not exist. Once the Facebook, redirects you back to the redirect_uri, the url contains access_token within url hash

http://domain/whatever-or-404.html#access_token=123

… now, if it does, it is parsed by locationExtractHash(), if it does not, the url contains error (user clicked Cancel button), the url contains error:

http://domain/whatever-or-404.html?error_reason=user_denied&error=access_denied&error_description=The+user+denied+your+request.

In case of error locationExtractError() parses and error. In both cases (error or access_token), the HTMLLoader window is closed and token is handled via confirmConnection(). Yeah, this way you can authorize !ANY! existing facebook application for your AIR app.

sHTiF also did a good job commenting all the functions, follow his the article to understand LocationChangeEvent listeners.

You may Leave a comment or Subscribe to Comments RSS or Trackback this entry.

Leave a comment

Please be polite and on topic. Your e-mail will never be published.