Jun 5, 2011

Facebook API ME 1.0: Tutorial

Hi, all

As I announced yesterday on Twitter, the first release of Facebook API ME is now available for download. Besides the release package, there is also a sample app, demonstrating how to implement the authentication process.

For while, only the version for eSWT is released. So, if your target device supports eSWT, you will be able to use this package in your Java ME app right away. I am also working on other versions targeted to Blackberry, LWUIT and Android. All of them are now under test phase. I hope to release them very soon. On the other hand, if you cant't wait, check out the source code from the project's repository. You need to add yourself to the project as an Observer member to be able to check out.

Let's start the tutorial!

Registering an App

You need to register an app on Facebook's Developer page. The process is pretty simple and straightforward. The goal of this registration is to obtain some keys that are required by authentication process: App Id, App Secret and Redirect Uri. This process is very similar to Twitter's app registration process.

Once you have the keys, let get to the API itself.

Browser Component

In your app, you need to display Facebook's Login page, so your user can enter his credentials and then grant access to your app. This process is implemented by the API. You just need to provide a browser component instance and then the API takes care of the rest. Considering the eSWT version, you need to provide an instance of Browser class.

Wrapper Class

Once the browser instance is created, you have to wrap it with an instance of AuthDialogWrapper class. This class is responsible for managing the authentication and delegates the events to your app. Considering the eSWT version, you have to instantiate the BrowserAuthDialogWrapper subclass.

Setting Up the Keys

The wrapper object must be set up, so it can handle the authentication process properly for you app. There are some "set" methods that can be used to inform your App Id, App Secret and Redirect Uri. If you prefer, you can enter the keys in the constructor.

...
Browser browser = new Browser(browserComp, SWT.TOP);


AuthDialogWrapper pageWrapper = new BrowserAuthDialogWrapper(browser);
pageWrapper.setAppId("App Id goes here");
pageWrapper.setAppSecret("App Secret goes here");
pageWrapper.setRedirectUri("Redirect Uri goes here");
...

Permissions

Most services provided by Facebook API requires explicit authorization by user. So, during the authentication process you must inform which permissions the services that you intend to work with, must be granted by user.

...
pageWrapper.setPermissions(new String[] {Permission.OFFLINE_ACCESS, Permission.PUBLISH_STREAM});
...

This code snippet says the app will request permission to perform authorized requests on behalf of the user at any time (OFFLINE_ACCESS) and publish content to a user's feed at any time PUBLISH_STREAM. For the full list of permissions provided by Facebook API, click here.

Authentication Events

In order to know if the user granted or denied permission to the app, you need to register a listener of the type AuthenticationListener. This interface has three methods:

- onAuthorize(String token)
- onAccessDenied(String message)
- onFail(String error, String message)

onAuthorize() means the user has granted permission to the app along with the Access Token. Keep this token, since you will use it to sign all your requests to Facebook API. This token works to identify your app. So, from this point on, you can dismiss the login page and start publishing links, comments, etc.

onAccessDenied() means the user has denied access to his Facebook account. It does not mean the user can change his mind later and then authorize your app.

onFail() means that something went wrong during the authentication process. Just try again!

...
pageWrapper.addAuthenticationListener(this);
...


public void onAuthorize(String token) {
    System.out.println("onAuthorize: " + token);
}


public void onAccessDenied(String message) {
    System.out.println("access_denied: " + message);
}


public void onFail(String error, String message) {
    System.out.println("error: " + error + " message: " + message);
}
...

Displaying Login Page

The Facebook's Login page will just be requested and displayed, as soon as the method login() be called.

...
pageWrapper.login();
...

Dispatching Requests

The API also provides a helper class, called Dispatcher, responsible for dispatching the requests, synchronously or asynchronously, to Facebook API. Each Dispatcher instance must be associated to an access token, so all requests dispatched be signed automatically.

...
Dispatcher dispatcher = Dispatcher.getInstance("Access Token goes here");
...

Dispatcher Events

When you work with asynchronous requests, it is recommended to register a listener in order to know whether they were successfully processed. This listener is defined by DispatcherListener interface. This interface has two methods:

- onComplete(Request request, Response response)
- onFail(Request request, Throwable error)

onComplete() means the request was processed successfully and returns the result (response).

onFail() means the request failed, returning the cause.

...
dispatcher.addDispatcherListener(this);
...


public void onComplete(Request request, Response response) {
    ...
}


public void onFail(Request request, Throwable error) {
    ...
}
...

Posting on User's Wall

To publish a text on user's wall is pretty simple. Just instantiate an object of Status class, informing the text in the constructor. The other constructor allows you to post a text on a friend's wall.

...
Status status = new Status("Text goes here");
dispatcher.dispatch(status); //synchronously


//or dispatcher.addToQueue(status); //asynchronously
...


Status status = new Status("Text goes here", "Friend's Id goes here");
dispatcher.dispatch(status);
...

Sharing Link


To share a link is as easy as posting on wall. Just instantiate an object of Link class, informing the URL in the constructor. The other constructor allows you to define how the link will be displayed.

...
Link link = new Link("Link's URL goes here");
dispatcher.dispatch(link);
...
Link link = new Link("Link'URL goes here", "Link's Picture Uri goes here", "Link's Name goes here", "Link's Caption goes here", "Link's Description goes here", "Link's Message goes here", "Friend's Id goes here");
dispatcher.dispatch(link);
...

Retrieving Friends List

To retrieve the user's friends list just instantiate an object of Friends class. This request returns an instance of Friends.Response, which is Enumeration.

...
Friends friends = new Friends();
Friends.Response friendsEnum = (Friends.Response) dispatcher.dispatch(friends);


while (friendsEnum.hasMoreElements()) {
    Friends.Response friend = (Friends.Response)friendsEnum.nextElement();
    String friendId = friend.getId();
    String friendName = friend.getName();
    ...
}
...

Profile Picture

To retrieve a friend's profile picture, create an instance of Picture class, informing the friend's Id in the constructor. This request returns an instance of Picture.Response.

...
Picture picture = new Picture("Friend's Id goes here");
Picture.Response pictureResp = (Picture.Response)dispatcher.dispatch(picture);
byte[] imageBytes = pictureResp.getData();
...

Revoking Authorization

Just in case an user decides to remove your app's authorization to access his Facebook account. For that, use the request defined by RevokeAuthorization class, informing the access token in the constructor. Once this request is processed, the access token is expired and you app will no longer be able to access the user's account. To access it again, the entire authentication process must be redone.

...
RevokeAuthorization revoke = new RevokeAuthorization("Access Token goes here");
dispatcher.dispatch(revoke);
...

Log out

The wrapper class AuthDialogWrapper has a method called logout(). Call this method in order to remove any cookie or logged user's data left by Facebook's Login page in our browser component. It is recommend to call this method when the user removes the app's authorization.

It is important to point out that all items presented here are valid for all versions of Facebook API ME. It does matter if you are working on Blackberry, LWUIT or Android. The steps are all the same, except at item 3, regarding the type of subclass. Each platform has its own subclass of AuthDialogWrapper.

So, I hope this tutorial has been useful for you guys, as well as the API itself.

As soon as the release of the other platforms are released, I will let everybody knwos.

See you in the next post...

17 comments:

Nilesh S. Yerunkar said...

Hello Friend,

I'm J2ME Developer.
I want to know where i got Browser eSWT API or Library ...

Please i need ur help...
if you already have then will send me on my nyerunkar@gmail.com ID..

Thanks,
Nilesh

Ernandes Mourão Júnior said...

Hi,

You cant add eswt library to your device. It is just like Java Me lirary: it must be available built-in.

Most Nokia ane Sony Ericsson devices support it.

Regards,
Ernandes

Nilesh S. Yerunkar said...

i got it in Nokia SDK..

Ernandes Mourão Júnior said...

Sure. You can get the jar file from Nokia SDK, but it is not gonna work just deploying it along with your app's binaries.

Nizaqat Ali said...

Dear,
your nice efforts but one thing i need connectivity with facebook from j2me. I have a bit problem to run above code on symbian sdk3. Can you tell me how i test it on symbian emulator? if you have code then plz share with me at syed.nizaqat@gmail.com

Ernandes Mourão Júnior said...

I am assuming you are using eSWT, right? To run on emulator you just have to build you app and then load it on the emulator.

There is a sample app in the project's website.

Check this out:

http://kenai.com/projects/facebookapime/downloads/download/FacebookAPIME-SWTSample-1.0.zip

Regards,

Nizaqat Ali said...

Dear,

Can i post text message,snapshot(photo) & a link to gather? How is it possible? please guide me.

Thanks

Ernandes Mourão Júnior said...

Yes! Check out the Link class and you will understand.

me marathi said...

Hi all,

I tried to run the sample midlet given by you which is "FacebookAPIME-SWTSample-1.0.zip"

The midlet compilation is successful without error, but when i run the midlet it show an error


Uncaught exception: java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationUid(RuntimeInfoImpl.java:81)
at org.eclipse.swt.internal.symbian.ApplicationIdWrapper.getApplicationId(), bci=5
at org.eclipse.swt.graphics.Device.(Device.java:126)
at org.eclipse.swt.graphics.Device.(Device.java:107)
at org.eclipse.swt.widgets.Display.(Display.java:192)
at FacebookAPIMESWTSampleMIDlet.run(FacebookAPIMESWTSampleMIDlet.java:50)
at java.lang.Thread.run(), bci=11
TRACE: , destroyApp threw an Exception
java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationId(RuntimeInfoImpl.java:70)
at org.eclipse.swt.internal.symbian.DefaultDisplayWrapper.get(), bci=3
at org.eclipse.swt.widgets.Display.getDefault(Display.java:557)
at FacebookAPIMESWTSampleMIDlet.exitEventLoop(FacebookAPIMESWTSampleMIDlet.java:46)
at FacebookAPIMESWTSampleMIDlet.destroyApp(FacebookAPIMESWTSampleMIDlet.java:37)
at javax.microedition.midlet.MIDletTunnelImpl.callDestroyApp(), bci=2
at com.sun.midp.midlet.MIDletPeer.destroyApp(), bci=8
at com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=398
at com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
at com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
at com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
at com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26
java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationId(RuntimeInfoImpl.java:70)
at org.eclipse.swt.internal.symbian.DefaultDisplayWrapper.get(), bci=3
at org.eclipse.swt.widgets.Display.getDefault(Display.java:557)
at FacebookAPIMESWTSampleMIDlet.exitEventLoop(FacebookAPIMESWTSampleMIDlet.java:46)
at FacebookAPIMESWTSampleMIDlet.destroyApp(FacebookAPIMESWTSampleMIDlet.java:37)
at javax.microedition.midlet.MIDletTunnelImpl.callDestroyApp(), bci=2
at com.sun.midp.midlet.MIDletPeer.destroyApp(), bci=8
at com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=398
at com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
at com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
at com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
at com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26

I am using Netbeans 7.0. As I am new in using eSWT, please help me if any one has the solution for this.

Thanks.

me marathi said...

Hi all,

I tried to run the sample midlet given by you which is "FacebookAPIME-SWTSample-1.0.zip"

The midlet compilation is successful without error, but when i run the midlet it show an error


Uncaught exception: java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationUid(RuntimeInfoImpl.java:81)
at org.eclipse.swt.internal.symbian.ApplicationIdWrapper.getApplicationId(), bci=5
at org.eclipse.swt.graphics.Device.(Device.java:126)
at org.eclipse.swt.graphics.Device.(Device.java:107)
at org.eclipse.swt.widgets.Display.(Display.java:192)
at FacebookAPIMESWTSampleMIDlet.run(FacebookAPIMESWTSampleMIDlet.java:50)
at java.lang.Thread.run(), bci=11
TRACE: , destroyApp threw an Exception
java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationId(RuntimeInfoImpl.java:70)
at org.eclipse.swt.internal.symbian.DefaultDisplayWrapper.get(), bci=3
at org.eclipse.swt.widgets.Display.getDefault(Display.java:557)
at FacebookAPIMESWTSampleMIDlet.exitEventLoop(FacebookAPIMESWTSampleMIDlet.java:46)
at FacebookAPIMESWTSampleMIDlet.destroyApp(FacebookAPIMESWTSampleMIDlet.java:37)
at javax.microedition.midlet.MIDletTunnelImpl.callDestroyApp(), bci=2
at com.sun.midp.midlet.MIDletPeer.destroyApp(), bci=8
at com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=398
at com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
at com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
at com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
at com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26
java.lang.NullPointerException: 0
at com.symbian.midp.runtime.MIDletSuiteAMS.getCurrentApplication(MIDletSuiteAMS.java:15)
at com.nokia.mj.impl.runtime.rtport.midp.RuntimeInfoImpl.getApplicationId(RuntimeInfoImpl.java:70)
at org.eclipse.swt.internal.symbian.DefaultDisplayWrapper.get(), bci=3
at org.eclipse.swt.widgets.Display.getDefault(Display.java:557)
at FacebookAPIMESWTSampleMIDlet.exitEventLoop(FacebookAPIMESWTSampleMIDlet.java:46)
at FacebookAPIMESWTSampleMIDlet.destroyApp(FacebookAPIMESWTSampleMIDlet.java:37)
at javax.microedition.midlet.MIDletTunnelImpl.callDestroyApp(), bci=2
at com.sun.midp.midlet.MIDletPeer.destroyApp(), bci=8
at com.sun.midp.midlet.MIDletStateHandler.startSuite(), bci=398
at com.sun.midp.main.AbstractMIDletSuiteLoader.startSuite(), bci=52
at com.sun.midp.main.CldcMIDletSuiteLoader.startSuite(), bci=8
at com.sun.midp.main.AbstractMIDletSuiteLoader.runMIDletSuite(), bci=161
at com.sun.midp.main.AppIsolateMIDletSuiteLoader.main(), bci=26

I am using Netbeans 7.0. As I am new in using eSWT, please help me if any one has the solution for this.

Thanks.

Facebook Development said...

I just love these information and i like this very much, very impressive.

Top Movie Trailers said...

Amazing, the up to date information has enhanced my knowledge allot. Keep posting such useful posts so that I can reap maximum benefits from them. Thank you Quit Smoking Tips.

cobetienca said...

Hi there,

I'm just a newbie in j2me and need to work with facebook. I found your project really amazing but the point is I can do nothing to run your example. Everytime I run I always got java.lang.NoClassDefFoundError: com/emobtech/facebook/api/auth/AuthenticationListener

I don't know if I missed any library setting up or not. My developement evironment is below:

1/ Eclipse Juno Mac 64 bit with MTJ
2/ Java SDK 3.0 for Mac
3/ I got swt.jar and org.eclipse.ercp.swt.qt.linux.x86_1.3.0.jar got from eclipse tool download page.

Please help me out, I'm in the middle of the desert!

Arindam................. said...

Hi, How can i fetch the user details like name, email id and current location??

Octacore Games said...

Hi all,

Here's a simple facebook api for j2me

http://www.youtube.com/watch?v=RT63EYLLkAA&feature=youtu.be

Ernandes Mourão Júnior said...

Is there any link to this solution? Thanks!

Eric Simmons said...

Great and Useful Article.

Online Java Course

Java Online Training

Java Course Online

Best Recommended books for Spring framework

Java Interview Questions












Java Training Institutes in Chennai

Java Training in Chennai

J2EE Training in Chennai

java j2ee training institutes in chennai

Java Course in Chennai