Facebook Wall(post/read) in Flash Professional for Adobe AIR (2 of 2)

Download Demo Files (Start & Completed versions for Part 1 & Part 2) In order for the completed code to work you have to put in your Facebook App ID and generated Facebook Social Plugin code in the required fields.

I would also recommend publishing for Adobe AIR 2.6 or 2.7. I have not tested this with AIR 3.0.

In this article, we will look deeper at the  ActionScript 3 SDK for Facebook Platform and use some of the API’s to securely log into Facebook, read data from the logged in user, post to the users wall and also post to a public Facebook page.

This article picks up/assumes that you have already registered as a Facebook Developer and created a Facebook application.  For more information on how to become a developer and create a Facebook application, click here and/or click here.

I would like to keep the explanations of each step fairly clear and straight forward.  Here are the tasks that we are going to accomplish in this article:

  1. Download and Install the ActionScript 3 SDK for Facebook Platform
  2. AS3 – Initialize your Facebook Application with your Flash project
  3. AS3 - Prompt the user to login to Facebook
  4. AS3 - Post to your wall
  5. AS3 - Post to a public page
  6. AS3 - Read the wall of a public page
Download and Install the ActionScript 3 SDK for Facebook Platform
There are many ways to communicate with Facebook using Flash, but some kind folks from the community and Adobe created an easy to use SDK, that will do all the heavy lifting for you.  Download the SDK from this link: Download ActionScript 3 SDK.  At this page you will notice there are different “.swc” files depending on your type of project.  For starters download everything… But in this article we will be using the Desktop API for Adobe AIR, GraphAPI_Desktop_xxxx.swc.

There are three targets for developing for Facebook: Web(Website and Facebook.com), Mobile, Desktop.

Download the as3corelib.swc Click here to download

The as3corelib.swc contains classes and utilities for MD5 hasing, image encoers, JSON, etc.

Click here to download the as3corelib.swc file that will be used to parase the JSON data that we will receive from Facebook. FYI in Flash Player 11 & Adobe AIR 3 there is a new native AS3 JSON API 

Add the .swc's to Flash Professional

Once you download the .swc, in Flash Professional, File -> ActionScript Settings -> Library path (tab) and navigate to the location of the .swc files.

Make sure you change the path to your location of: as3corelib.swc andGraphAPI_Desktop_xxx.swc , if you do not change it, you will get errors.

Once you have added the path to the .swc file, you have access to all of the Facebook/ActionScript API and the

Click here to view the online docs.

Facebook ActionScript API

Download the files used in this exercise

Download Demo Files (Start & Completed versions for Part 1 & Part 2)

  • facebookNOTO.fla
  • Tools.as – used to dump objects and arrays to the output panel or string, making an easy way to read the JSON Facebook data
  • NotoFB.as – used in Part 1 – Creating a Facebook Like Button in Flash Professional for Adobe AIR, already has completed code for the Facebook “LIKE” button

The NotoFB.as file will look like this:

package{
	import flash.display.Sprite;
	
	import flash.html.HTMLLoader;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowType;
	import flash.net.URLLoader;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.events.MouseEvent;

public class NotoFB extends Sprite{

	private var html:HTMLLoader;
	private var options:NativeWindowInitOptions;
	private var boundaries:Rectangle;

public function NotoFB(){

		html = new HTMLLoader();

		html.scrollV = 200;
		html.navigateInSystemBrowser = true;

		options = new NativeWindowInitOptions();
		options.type = NativeWindowType.NORMAL;
		boundaries = new Rectangle(950,55,300,300);

		loadFacebookLikeButton();

}

        private function loadFacebookLikeButton():void {
        var myString:String = 'ADD YOUR HTML5 CODE FROM YOUR PASTED FACEBOOK SOCIAL';

	html = HTMLLoader.createRootWindow(false,options,false,boundaries);
	html.loadString(myString);
	addChild(html);
	html.width = 292;
	html.height = 60;
	html.x = 15;
	html.y = 0;

	html.addEventListener(Event.COMPLETE, completeHandler);

}
	private function completeHandler(event:Event):void {

			trace("Facebook Like Button Loaded");

  }
 }
}

Create an init() function. This function will make an initial call to your Facebook application. And also define the event handlers for the buttons on the page. Update the NotoFB constructor function to make a call to the init() function.  Make sure you put your Facebook Application ID in the first parameter in the FacebookDesktop.init() function.
		public function NotoFB() {

			html = new HTMLLoader();

			html.scrollV = 200;
			html.navigateInSystemBrowser = true;

			options = new NativeWindowInitOptions();
			options.type = NativeWindowType.NORMAL;
			boundaries = new Rectangle(950,55,300,300);

			loadFacebookLikeButton();

			init();
		}

		private function init():void {
			FacebookDesktop.init("YOUR APP ID HERE", handleLogin);
			
			authorize_btn.addEventListener(MouseEvent.CLICK, onAuthorize);
			post_btn.addEventListener(MouseEvent.CLICK, onYourPost);
			get_btn.addEventListener(MouseEvent.CLICK, onGet);
			postPage_btn.addEventListener(MouseEvent.CLICK, onPagePost);
			logout_btn.addEventListener(MouseEvent.CLICK, onLogOut);
			
		}

To make calls via ActionScript to the Facebook Graph API we use the .api() method.  In this case. FacebookDesktop.api().  You can find out more about all of the available Facebook Graph API calls by visiting http://developers.facebook.com/docs/reference/api/ and there is also an interactive Graph explorer (https://developers.facebook.com/tools/explorer ) that allows you to test calls to your app. One thing to keep in mind, by visiting the Facebook Developer docs it does not base their examples for ActionScript. We use the Graph API and insert it into the FacebookDesktop.api() method.  So you must review the Facebook Developer Graph API documentation, as well as the Facebook ActionScript SDK.
private function onAuthorize(e:MouseEvent):void {

			FacebookDesktop.login(handleLogin,"publish_stream");
		}
		private function onLogOut(e:MouseEvent):void {
			FacebookDesktop.logout();
			desc.text = "logout";
		}
		
		
		private function onYourPost(e:MouseEvent):void {
			FacebookDesktop.api("/me/feed",submitPostHandler,{message:post_txt.text}, "POST");
		}

		private function onPagePost(e:MouseEvent):void {
			FacebookDesktop.api("/229237793792361/feed", submitPostHandler, {message:post_txt.text}, "POST");
		}

		private function onGet(e:MouseEvent):void {
			FacebookDesktop.api("/229237793792361/feed", submitPostHandlerPage, null, "GET");
		}


		private function handleLogin(session:Object, fail:Object):void {
			if (session != null)	 {
				userImage.source = FacebookDesktop.getImageUrl(session.uid,"large");
				desc.text = session.user.name + "\n";
			}
		}

		private function submitPostHandler(result:Object, fail:Object):void {
			desc.appendText("\n\nRESULT:\n" + JSON.encode(result));

		}

The code below uses the Tools.as file to loop through the JSON so it is easy to read.  I downloaded the original Tool.as from here, but the one using in this project has been tweeked a little.
		private function submitPostHandlerPage(result:Object, fail:Object):void {

			var arr:Array = (JSON.decode(JSON.encode(result)) as Array);
			trace("Number of records: " + arr.length);
			
			var myString:String = Tools.pr(arr);
			desc.appendText(myString);

			desc.appendText("Message: " + arr[9].message);

		}

The final code is here:
package {

	import com.facebook.graph.FacebookDesktop;
	import com.adobe.serialization.json.JSON;
	import Tools;
	import flash.display.Sprite;
	import flash.html.HTMLLoader;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowType;
	import flash.net.URLLoader;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class NotoFB extends Sprite {

		private var html:HTMLLoader;
		private var options:NativeWindowInitOptions;
		private var boundaries:Rectangle;

		public function NotoFB() {

			html = new HTMLLoader();

			html.scrollV = 200;
			html.navigateInSystemBrowser = true;

			options = new NativeWindowInitOptions();
			options.type = NativeWindowType.NORMAL;
			boundaries = new Rectangle(950,55,300,300);

			loadFacebookLikeButton();

			init();
		}

private function init():void {
			FacebookDesktop.init("YOUR APP ID HERE", handleLogin);
			
			authorize_btn.addEventListener(MouseEvent.CLICK, onAuthorize);
			post_btn.addEventListener(MouseEvent.CLICK, onYourPost);
			get_btn.addEventListener(MouseEvent.CLICK, onGet);
			postPage_btn.addEventListener(MouseEvent.CLICK, onPagePost);
			logout_btn.addEventListener(MouseEvent.CLICK, onLogOut);
			
		}

private function loadFacebookLikeButton():void {
			var myString:String = "FACEBOOK SOCIAL HTML CODE HERE";

			html = HTMLLoader.createRootWindow(false,options,false,boundaries);
			html.loadString(myString);
			addChild(html);
			html.width = 292;
			html.height = 60;
			html.x = 15;
			html.y = 0;

			html.addEventListener(Event.COMPLETE, completeHandler);


		}

private function completeHandler(event:Event):void {

			trace("Facebook Like Button Loaded");

		}

private function onAuthorize(e:MouseEvent):void {

			FacebookDesktop.login(handleLogin,"publish_stream");
		}
private function onLogOut(e:MouseEvent):void {
			FacebookDesktop.logout();
			desc.text = "logout";
		}
		
private function onYourPost(e:MouseEvent):void {
			FacebookDesktop.api("/me/feed",submitPostHandler,{message:post_txt.text}, "POST");
		}

private function onPagePost(e:MouseEvent):void {
			FacebookDesktop.api("/229237793792361/feed", submitPostHandler, {message:post_txt.text}, "POST");
		}

private function onGet(e:MouseEvent):void {
			FacebookDesktop.api("/229237793792361/feed", submitPostHandlerPage, null, "GET");
		}


private function handleLogin(session:Object, fail:Object):void {
			if (session != null)	 {
				userImage.source = FacebookDesktop.getImageUrl(session.uid,"large");
				desc.text = session.user.name + "\n";
			}
		}

private function submitPostHandler(result:Object, fail:Object):void {
			desc.appendText("\n\nRESULT:\n" + JSON.encode(result));

		}

private function submitPostHandlerPage(result:Object, fail:Object):void {

			var arr:Array = (JSON.decode(JSON.encode(result)) as Array);
			trace("Number of records: " + arr.length);
			
			var myString:String = Tools.pr(arr);
			desc.appendText(myString);

			desc.appendText("Message: " + arr[9].message);

		}
	}
}

 

Save/Test your movie.

  • Click on Login, enter your credentials
  • You can Post on your wall, you can post on a page wall (Change the id in the onGet/onPagePost to post to another page)
  • You can read a page’s wall

Tags: , ,

Creating a Facebook Like Button in Flash Professional for Adobe AIR (1of2)

Download Demo Files (Start & Completed versions for Part 1 & Part 2) In order for the completed code to work you have to put in your Facebook App ID and generated Facebook Social Plugin code in the required fields.

I would also recommend publishing for Adobe AIR 2.6 or 2.7. I have not tested this with AIR 3.0.

The use of the Facebook Like Button in Flash has been pretty difficult to produce.  There have been some “work arounds” and “hacks”, but nothing as clear and direct as using the API’s from the  ActionScript 3 SDK for Facebook Platform .

Now the ActionScript 3 SDK for Facebook Platform currently DOES NOT have any API’s that allow you to create the “Like” button, but using some other ActionScript API’s and a Facebook’s Social Plugin we can incorporate the “Like Button”.

*Important note*

- This example is publishing for Adobe AIR and not the Flash Player for the web.
ActionScript 3 SDK for Facebook Platform currently does not have any API’s for the “Like Button”

There are two key components here to get started:

  1. Facebook Social Plugins - Facebook code snippets that allow you to incorporate Facebook social feature in your website without having to know any of the Facebook Graph APIs.
  2. Adobe AIR – HTMLLoader class - An Adobe AIR container that will display HTML content.

Create your “Like Button” Social Plugin

The Facebook Social Plugins allow you to quickly integrate your and/or other Facebook data into your HTML pages without having to know anything about the Graph API, FBML, etc.  We are going to use the Facebook Social Plugin (let Facebook do the dirty work) and then plug the code into our AIR app.

  1. Visit: http://developers.facebook.com/docs/reference/plugins/like-box/

    Facebook Social Plugin Custom Settings

  2. Fill in your desired fields. You can use any public Facebook Page URL for the URL section. (eg. myNOTO (shameless plug), Adobe, FlashPlatform, etc)
  3. Click the “Get Code” button
  4. Click on “HTML5” and copy both sections of code to a new Dreamweaver document or blank document.

    Facebook HTML5 Social Plugin

Create your HTML code 

In order for the code to display in the HTMLLoader object, it must be placed in HTML.

  1. Create a new HTML5 document.
  2. Paste the “<div>” tag elements after the “<body>” tag.
  3. Change all double quotes to single quotes. This will allow the code to be used as one String in Flash.
  4. Add “https:” in front of ” //connect.facebook.net

Facebook Social Plugin HTML

You can copy and paste the code below. Change YOUR_APP_ID to your Facebook Application ID.

<!DOCTYPE HTML><html><head><meta charset='UTF-8'><title>Untitled Document</title></head><body><div id='fb-root'></div><script>(function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) {return;}js = d.createElement(s); js.id = id;js.src = 'https://connect.facebook.net/en_US/all.js#xfbml=1&appId=YOUR_APP_ID';fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><div class='fb-like-box' data-href='https://www.facebook.com/myNOTO' data-width='292' data-show-faces='false' data-stream='false' data-header='false'></div></body></html>

Incorporate your “LIKE” button into Flash (AIR Application) Download Demo Files (Start & Completed versions for Part 1 & Part 2) 

  1. Open the file named “facebookNOTO.fla” from here.
  2. Save your file in your desired directory.
  3. You will notice: (these components will be used fully later in Part 2)
    1. UILoader
    2. Dynamic Text Field
    3. Text Area Component
    4. 5 buttons
  4. Create a Document class.  File -> New -> ActionScript File
  5. Save the file in the same directory as your “.fla” and name it ‘NotoFB.as“ and it is CASE SENSITIVE!!!

This file(NotoFB.as) will be used as our Document Class for the facebookNOTO.fla file.

Create your document class (NotoFB.as)

Create the package, class definition and constructor function

package{
	import flash.display.Sprite;
	
public class NotoFB extends Sprite{
public function NotoFB(){

  }
 }
}

Import the following classes that will be used in this example.
package{
	import flash.display.Sprite;
	
	import flash.html.HTMLLoader;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowType;
	import flash.net.URLLoader;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.events.MouseEvent;

public class NotoFB extends Sprite{
public function NotoFB(){

  }
 }
}

Define properties and initial values.  The added code creates a new instance of the HTMLLoader class and defines the options and boundaries for the HTMLLoader object.
package{
	import flash.display.Sprite;
	
	import flash.html.HTMLLoader;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowType;
	import flash.net.URLLoader;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.events.MouseEvent;

public class NotoFB extends Sprite{

	private var html:HTMLLoader;
	private var options:NativeWindowInitOptions;
	private var boundaries:Rectangle;

public function NotoFB(){

		html = new HTMLLoader();

		html.scrollV = 200;
		html.navigateInSystemBrowser = true;

		options = new NativeWindowInitOptions();
		options.type = NativeWindowType.NORMAL;
		boundaries = new Rectangle(950,55,300,300);

  }
 }
}

Create a function that will add the HTMLLoader object on the stage. Add the function the constructor function.
package{
	import flash.display.Sprite;
	
	import flash.html.HTMLLoader;
	import flash.display.NativeWindowInitOptions;
	import flash.display.NativeWindowType;
	import flash.net.URLLoader;
	import flash.geom.Rectangle;
	import flash.events.Event;
	import flash.events.MouseEvent;

public class NotoFB extends Sprite{

	private var html:HTMLLoader;
	private var options:NativeWindowInitOptions;
	private var boundaries:Rectangle;

public function NotoFB(){

		html = new HTMLLoader();

		html.scrollV = 200;
		html.navigateInSystemBrowser = true;

		options = new NativeWindowInitOptions();
		options.type = NativeWindowType.NORMAL;
		boundaries = new Rectangle(950,55,300,300);

		loadFacebookLikeButton();

}

        private function loadFacebookLikeButton():void {
        var myString:String = 'ADD YOUR HTML5 CODE FROM YOUR PASTED FACEBOOK SOCIAL';

	html = HTMLLoader.createRootWindow(false,options,false,boundaries);
	html.loadString(myString);
	addChild(html);
	html.width = 292;
	html.height = 60;
	html.x = 15;
	html.y = 0;

	html.addEventListener(Event.COMPLETE, completeHandler);

}
	private function completeHandler(event:Event):void {

			trace("Facebook Like Button Loaded");

  }
 }
}

Paste the code that you copied from the Facebook Social Plugin Page.
var myString:String = 'ADD YOUR HTML5 CODE FROM YOUR PASTED FACEBOOK SOCIAL';

After you paste your code, save your NotoFB.as file and return to Flash and set your class as the Document Class for your “.fla” file.

Document Class Properties Panel

 

Test your movie. You will see the “distractor” animation.  When you click on the “LIKE” button you will be prompted to log into Facebook.

 

Part 2 – Facebook Wall(post/read) in Flash Professional for Adobe AIR

 

Tags: , , , , , , , ,

I’m an Adobe Community Professional – ACP

From my small start as a Flash 3 (whatever you call it back then) to an ACP, ACI and everything else. I am thrilled and honored to have been chosen as a Adobe Community Professional.  I look forward to continue to assist the community with questions/concerns/comments on Flash, ActionScript, and anything else I could help out with…  You can view other ACP’s in around the world, here.

Feel free to contact me:  Twitter @thesminc Email: asklou@thesminc.com

The Document Class – Why is it so important? pt. 1

Through my travels as an instructor, I always get the question, What is a Document Class?  Well the answer is simple, but the possibilities are extreme.  During this article, I would like to explain some of the most important things to know about a Document Class….Mainly a Document Class is “Your SWF file”!

First of all, the document class is optional.  Ok, it’s 2011, most seasoned Flash Developers are NOT using the timeline anymore and are using the Document Class. And every year as someone reaches excellence, there is someone born…New to Flash/ActionScript. Someone, right now, is holding on to the timeline, as if their life depended on it. So, whatever category you may fall into, one thing is certain, Flash is OPEN to you.  Flash will let you do, pretty much, whatever you want.

  • Create animation and ActionScript on the timeline
  • Create animation without the timeline, using ActionScript
  • Create animation with AND without the timeline, together…

You do not have use a Document Class, but you should at least understand it.

One of the reasons why you should understand it:

  • 99% of all of the examples in the Adobe Help Docs, online articles and many books are written using a document class.

So, if you would like to leverage the power of “learn by example”, then you need to know, if nothing else, NOT how to WRITE a document class, but how to USE a document class.

So first things first, without getting too complicated.

  • Part 1. Two of the main uses of a Document Class
  • Part 2. Implement a Document Class.

Here are two of the most important topics when working with the document class?

  • Separate your code from the timeline
  • Let your SWF file become a Sprite vs a MovieClip

Separating your code from the timeline

I mentioned, the document class is optional.  You can have the same functionality with code running on the timeline and in the document class. The rule of thumb is if you want your ActionScript to be more portable, easier to update, and free from you FLA, then use a document class.  Take a look at the code below.

ActionScript on the Timeline inside of an FLA.
The ActionScript below draws a red circle on the stage with an x/y = 100 and radius = 50.

// DRAW A CIRCLE ON THE STAGE
var myCircle:Sprite = new Sprite();
myCircle.graphics.beginFill(0xFF0000);
myCircle.graphics.drawCircle(100, 100, 50);
addChild(myCircle);

ActionScript on in a Document Class.
The ActionScript below draws a red circle on the stage with an x/y = 100 and radius = 50.

package {

	import flash.display.Sprite;
	
	public class DCcode extends Sprite{
		
		public var myCircle:Sprite;

		public function DCcode() {
			// DRAW A CIRCLE ON THE STAGE
			myCircle = new Sprite();
			myCircle.graphics.beginFill(0xFF0000);
			myCircle.graphics.drawCircle(100, 100, 50);
			addChild(myCircle);

		}

	}

}

Both of the options above give us the same results.  As you see, there is more ActionScript that must be written in a Document Class, but it’s well worth the time. Next, I will discuss one of the benefits of using a Document Class.

Your SWF as a Sprite not a MovieClip

This may or may not be a surprise to you, but by default an SWF file is nothing more than a MovieClip.  Yes, that’s right, a MovieClip.  A MovieClip that contains other MovieClips, bitmaps, symbols, video, text, etc….  With that being said, a MovieClip is a very powerful symbol, actually, the most powerful symbol.  The thing that makes a MovieClip unique is the timeline.  The timeline allows you to create linear animations and also create linear dynamic functionality with ActionScript on keyframes.

Enter the Sprite Object.

The Sprite object, in all simple terms, can be considered a new symbol in Flash.  The only thing is that when you are converting a shape to a symbol, Sprite is not an option.  Your available options are, Graphic, Button, and MovieClip.  There are many ways to use Sprite objects in Flash, but our conversation here, is just focusing on the Document Class.

The main thing to remember about the Sprite Object/Symbol/Class is:

  • The Sprite is identical to the MovieClip. Except for one thing… The Sprite does NOT have a timeline.

In many cases, when we use MovieClips, we do not use the timeline in that MovieClip.  And in cases like these, the timeline is actually taking up unnecessary resources.  For this reason, Adobe created the Sprite class, to give us the ability to have the same power of the MovieClip, but not have to worry about the resources consumption that comes along with a MovieClip.

So now by using a Document Class, your SWF file can actually be a Sprite vs a MovieClip. Once again, look at the code below. On line 5, “extends Spite”, will make your SWF file become a Sprite.  Note: A Document Class can ONLY be a MovieClip or a Sprite.

package {

	import flash.display.Sprite;
	
	public class DCcode extends Sprite{
		
		public var myCircle:Sprite;

		public function DCcode() {
			// DRAW A CIRCLE ON THE STAGE
			myCircle = new Sprite();
			myCircle.graphics.beginFill(0xFF0000);
			myCircle.graphics.drawCircle(100, 100, 50);
			addChild(myCircle);

		}

	}

}

In part 2 of this article, I will discuss how to implement and use a Document Class.

Tags: , , ,

Google Voice Porting – Why? I Love It.

It’s 2011 folks, times are changing, Change We Can Believe In?… Ok, I’m not running for President, but sounds like a good slogan.

First of all, I’m not your normal user….I’m a UberTechie…I have, to have the latest gagets, the coolest clothes and be in the know with the latest trends…  I have multiple cell phones for development, Android, BlackBerry and iPhone. So with that being said..I may be able to give the average consumer some advice..

So Google announced the ability to port your phone number to Google Voice. What does that mean?

Well, let’s say my phone number is 999-9999 and I have two cell phones, a landline, and many IMs (GTalk, AOL, BBM, etc). I really do not need to go into depth, but you can understand the complexity, that multiple ways to communicate can cause. So enters.. Google Voice, hereafter referred to as, GV (my lawyer lingo).

So, GV without porting, allows you to create a new number(???-????) and “link” it to your cell phones, land lines and a few IMs. So when someone calls your GV number, it will connect to all of the phones that are “linked” to that number. I’ve used GV with this setting and I have really enjoyed it. The only thing is that I really never gave anyone my GV number. Now, I could have used it for business, friends, or whatever. But I did not.

So, now as of January 2011, Google now allows you to use your “everyday” number as your GV number. So when someone calls my 999-9999 number, it will connect to all of my “linked” numbers. So what’s the big deal?

Let’s look at the “pros”.

  • Always keep your phone number, regardless of your device. (Love BlackBerry for build and service, love Android for flexibility, love iPhone for continuity)
  • I have two cell phones (777-7777 and 888-8888), now when someone calls my 999-9999 number it will ring both phones(777 & 888). So I can leave my Droid at home and take my BlackBerry or vice versa.  (My BlackBerry looks better with my suit, like my Armani watch vs my Nike Watch, think about it…..)
  • Or I can, at anytime, select which phones will ring and which phones will not.
  • Select (via your contacts) which phone rings.  So create a Group and have that group forward to your BlackBerry and have another group forward to your Android.
  • I love to text, but I hate to text on my phone…. With GV Porting, I now can text from my computer vs my cell phone.  Hence, I type 65+ wpm, so you can imagaine how eaiser it is to Type & Text, then to Touch & Text.
  • Personalize voicemail for callers.
  • If I’m in front of my computer and the phone rings I can answer the phone on my computer. Yes, click “Answer” and start talking…
  • I’m not even touching the cheaper Long distance rates……
  • Become that true Playboy, businessman or UberTechie.

Let’s look at the “cons”.

  • It costs $20 (may not be a “con” if  you are someone like me). And if you are not careful, can cause you an early termination fee.
  • Forces you to manage multiple devices, landlines, etc
  • GV can be a little confusing. You have to get in the mindset that “In” means GV and “Out” mens your number.
  • GV can handle your Text Messages and VocieMail, so your cell phone will get multiple notifications. One text message can trigger multiple notifications on your cell.
  • Look unorganized to your friends for having more than one cell phone.
  • Become that true Playboy, businessman or UberTechie.
  • I may be missing a few more (let me know in your comments)

All in all, GV porting is worth checking out.  When I wake up, I have a choice of suits, shirts, watches, and even underwear….why not phones.

It may not be something you are ready for now, but in the future… It may be part of our everyday life.

BlackBerry Playbook – Icons and Splash Screen

The XML below is called blackberry-tablet.xml.  It should be generated automatically when creating a new project. But if you do not have this file, you can create one using your favorite HTML editor.

<qnx>
  <initialWindow>
    <systemChrome>none</systemChrome>
    <transparent>false</transparent>
  </initialWindow>
  <publisher>YOUR NAME HERE</publisher>
  <category>core.internet</category>
  <icon>
  	<image>blackberry-tablet-icon.png</image>
  </icon>
  <splashscreen>slpashscreen.png</splashscreen>
</qnx>

To apply a custom icon:
Add this line to the XML

<icon><image>ICONNAME.png</image.</icon>

To apply a custom splash image:
Add this line to the XML

<splashscreen>IMAGENAME.png</splashscreen>

Also, I noticed that if you leave <transparent>true</transparent>, then your application will be transparent and you will see the desktop of the Playbook behind your app.  (May be useful)???

The new BlackBerry Playbook SDK has been released.  There are a lot of changes to the simulator and SDK.  Renaun Erickson created a video explaining some of the changes.  You can view the video below.

Run Through of PlayBook Beta3 AIR SDK Updates from Renaun Erickson on Vimeo.

Tags:

Flash Builder / Flex errors

As with all programming, we run across some errors that we just cannot easily figure out.  When dealing with FlashBuilder, one way to “start with a clean slate” is to perform a “Clean”.  By doing this, at least you know that your Flash Builder project is recompiled with all of the latest and previous assets.  And if you get an error after this?  Well, time to check your code.

To perform a “Clean”:

  • Go to “Project” menu.
  • Select “Clean”

Why(not) Google TV?

I’m typing this blog post from my Google TV while the TV is playing in (Picture in Picture). (Thought I might add)

The Google TV is game changing!

Thanks to (Adobe/Google/Logitech) for offering it as a Giveaway to Developers!

I had a few reservations about this device before receiving it. ( Just because I had no idea what it did.)

What do I need it for? Am I really going to use it? Can App development grow on this platform? Will I get all of my channels?

Well, after receiving the Logitech Revue and unboxing. Once the physical connections were made, there were 12 easy steps to follow. First of all, since this device was going to be on our main TV set, I decided to create a “family” Gmail account that the entire family can use. I can use this account to pull all of our shared YouTube videos, Picasa photos, etc., in one centralized account.

I am impressed with the device/component integration, but that’s to be expected from Logitech. The Revue picked up my Verizon cable box, my HD TV and my Audio receiver. So, even before I interacted with Google TV, I had a very cool universal remote control! The entire setup process lasted about 15-20 minutes, but it was very smooth and direct. (for me at least).

I kept hearing all this chatter about NBC, CBS, etc, pulling their content from Google TV. This made me think that I actually would NOT get these stations. (I know that may sound crazy) But they are actually blocking the web/video content. But WHO CARES, I’m on a TV? Duh? With DVR & onDemand? Duh? I doubt I would have visited their sites anyway. It’s really worse off for them, because they are leaving themselves out of a whole new wave of entertainment and reach. I’m glad to know that Google isn’t “web blocking”, unlike some other software companies that control what you can view.

I’ve also heard a lot of chatter about Google TV not having many Apps. But if you remember the original iPhone, we went about a year and a half before we got anything close to Apps.  At least with Google, you know it’s only a matter of time. (Short time).

After, the setup was completed, the Revue rebooted and the Google welcome screen appeared. The first thing I did was go to YouTube. I had to see how well the videos played on my screen as well as the quality. Upon, visiting the youtube.com site on Google TV, I was prompted to use YouTube Lean back. A sort of scaled back, but extremely powerful version of You Tube. And since I also have a Android phone, I downloaded the YouTube Leanback App, to connect and control the video playback. Overall, the video playback was very smooth, but the quality was about the same, unless you choose a HD video. So I watched the Kayne West – Runaway Film, the quality was good and having the Revue connected to my AV Receiver the sound was great, adding a lot to the experience.

Next, I visited a few websites, logged into the Pandora app, checked out some of the settings (which is very similar to our Android devices), and actually set my DVR from within the Google TV app.

Another thing that I like is the ability to search for a TV show that you may want to watch.  This beats channel surfing!  The search capabilities are great and it also give you an option to search TV or the web.

So my main purpose that I see for Google TV, (for me at least), is the fact that I can now watch TV without my computer in my lap! The surfing experience is great!  And when my wife and I are debating about some actor, movie, song, or whatever, Google is right at my fingertips!!

Overall, you may see Google TV on the web, or in your local Best Buy, but until you use it (and each of us will use it differently), you do not know what you are missing.

Give it a try, demo, or buy!

Tags: ,

Adobe MAX 2010: Device Lab Interview

During my wonderful time at Adobe MAX, I had the pleasure running into Mike Potter of Adobe Developer Relations. We sat down for a few minutes to talk about Mobile Development using the Flash Platform. Check it out below. (I’m at the 2:00 mark)

Blackberry Playbook – Flickr Feed Demo

I wanted to play around with some of the Blackberry Playbook Components, so I decided to use the List Component.  This code below shows you how to bring in a Flickr feed into your List component and display each image once you click on an item. In this case I’m using the Flick Feed to Adobe MAX 2010.

Replace the YOUR_API_KEY with your own API key and everything should work fine.

package
{
	// IMPORT STATEMENTS
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;
	import flash.events.KeyboardEvent;
	
	import qnx.ui.buttons.LabelButton;
	import qnx.ui.data.DataProvider;
	import qnx.ui.listClasses.List;
	import qnx.ui.listClasses.ListSelectionMode;
	import qnx.ui.events.ListEvent;
	
	[SWF(width="1024", height="600", backgroundColor="#181818", frameRate="30")]
	
	// CLASS DEFINITION
	public class BBFlickr extends Sprite
	{
		// VARIABLE DECLARATION
		public var myData:DataProvider;
		public var myButton:LabelButton;
		public var list:List;
		public var xml:XML;
		public var bbList:XMLList;
		public var xmlLoader:URLLoader;
		public var myText:TextField;
		public var holder:Loader;
		public var myFormat:TextFormat;
		
		// CONSTRUCTOR FUNCTION
		public function BBFlickr()
		{
			myText = new TextField();
			myText.autoSize = TextFieldAutoSize.LEFT;
			addChild(myText);
			myText.x = 350;
			
			myFormat = new TextFormat();
			myFormat.font = "Verdana";
			myFormat.color = 0xFFFFFF;
			myFormat.size = 24;
			myFormat.bold = true;
			
			myText.defaultTextFormat = myFormat;
			
			holder = new Loader();
			addChild(holder);
			holder.x = 350;
			holder.y = 50;
			
			myData = new DataProvider();
			
			list = new List();
			list.width = 320;
			list.height = 768;
			list.selectionMode = ListSelectionMode.SINGLE;
			
			list.addEventListener(ListEvent.ITEM_CLICKED, onClick);
			
			xmlLoader = new URLLoader();
			xmlLoader.load(new URLRequest("http://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos&api_key=YOUR_API_KEY&photoset_id=72157624748850345"));
			xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded);
			
		}
		// EVENT HANDLERS
		private function onClick(e:ListEvent):void{
			var bbLabel:String;
			if(e.target.selectedItem.label == ""){
				// GIVE THE LABEL A DEFAULT NAME
				bbLabel = "MAX 2010";
			}else{
				bbLabel = e.target.selectedItem.label;
			}
			
			myText.text = bbLabel;
			// SYNTAX FOR STATIC FLICKR 
			//http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg
			//
			holder.load(new URLRequest("http://farm"  +  list.selectedItem.data.farm + ".static.flickr.com/" + list.selectedItem.data.server + "/" + list.selectedItem.data.id + "_" + list.selectedItem.data.secret + ".jpg"));
			
		}
		private function xmlLoaded(e:Event):void {
			xml = XML(e.target.data);
			bbList = xml.photoset.children();
			trace(bbList);
			for (var i:int = 0; i < bbList.length(); i++) {
				var obj:Object = new Object();
				obj.farm = bbList[i].@farm;
				obj.server = bbList[i].@server;
				obj.id = bbList[i].@id;
				obj.secret = bbList[i].@secret;
				var bbTitle:String;
				if(bbList[i].@title == ""){
					// GIVE THE TITLE A DEFAULT NAME
					bbTitle = "MAX 2010";
				}else{
					bbTitle = bbList[i].@title;
				}
				myData.addItem({label:bbTitle, data:obj});
			}
			list.dataProvider = myData;
			addChild( list );
			
		}
	}
}