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.

Leave a comment

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