Java ME & OAuth: Impossible? Not really!

ernandesmjr
@ernandesmjr Ernandes Jr 

Hi,

Many of Java ME developers may think it was impossible to authenticate with Twitter using OAuth, since Java ME there is no browser component. That's why xAuth was the only way to go. This is no longer true.

From version 1.8 Twitter API ME (http://www.twitterapime.com) allows Java ME to go OAuth easily, by implementing OAuth + oob (out-band-mode) and using the device's external browser. Using oob, the app's flow is the following:

  • Start the MIDlet
  • The Twitter's login page is displayed via external browser
  • User authenticates and Twitter returns a PIN code
  • User closes the browser and returns to the app
  • User enters PIN code in a text field and presses Login
  • User is authenticated!
  1. public class TwitterAPIMEJavaMEOAuthSample extends MIDlet
  2.  implements OAuthDialogListener, CommandListener {
  3.     ...
  4.     public TwitterAPIMEJavaMEOAuthSample() {
  5.        form = new Form("Twitter API ME");
  6.        field = new TextField("PIN:", "", 15, TextField.NUMERIC);
  7.       form.addCommand(new Command("Login", Command.OK, 0));
  8.         form.addCommand(new Command("Exit", Command.EXIT, 0));
  9.        form.append(field);
  10.         form.setCommandListener(this);
  11.      pageWrapper = new MIDletOAuthDialogWrapper(this);
  12.       pageWrapper.setConsumerKey(CONSUMER_KEY);
  13.       pageWrapper.setConsumerSecret(CONSUMER_SECRET);
  14.         pageWrapper.setOAuthListener(this);
  15.         pageWrapper.login();
  16.    }
  17.   protected void startApp() throws MIDletStateChangeException {
  18.       Display.getDisplay(this).setCurrent(form);
  19.  }
  20.   ...
  21.     public void commandAction(Command cmd, Displayable displayable) {
  22.       if (cmd.getCommandType() == Command.OK) {
  23.           pageWrapper.login(field.getString());
  24.       } else if (cmd.getCommandType() == Command.EXIT) {
  25.          notifyDestroyed();
  26.      }
  27.   }
  28.   public void onAuthorize(Token accessToken) {
  29.        Credential c = new Credential(CONSUMER_KEY, CONSUMER_SECRET, accessToken);
  30.      UserAccountManager uam = UserAccountManager.getInstance(c);
  31.         try {
  32.           if (uam.verifyCredential()) {
  33.               TweetER.getInstance(uam).post(new Tweet("test: " + System.currentTimeMillis()));
  34.              showMessage("Tweet posted!");
  35.             }
  36.       } catch (Exception e) {
  37.             showMessage("Error by posting tweet.");
  38.       }
  39.   }
  40.   public void onAccessDenied(String message) {
  41.        showMessage("Access denied!");
  42.    }
  43.   public void onFail(String error, String message) {
  44.      showMessage("Error by authenticating user!");
  45.     }
  46.   ...
  47. }

To download the full source code, access the link below:

http://kenai.com/projects/twitterapime/downloads/download/Miscellaneous/TwitterAPIME-JavaME-OAuthSample.zip

I hope you guys enjoy it.

Regards,

2 years 24 weeks ago

Replies

Ayansys
@Ayansys Ayansys

Hi Ernandes,
i am getting an exception
java.lang.IllegalStateException: Invalid state: call login() method first.
at com.twitterapime.xauth.ui.OAuthDialogWrapper.login(OAuthDialogWrapper.java:309)
at Twitter.actionPerformed(), bci=27
at com.sun.lwuit.util.EventDispatcher.fireActionSync(), bci=19
at com.sun.lwuit.util.EventDispatcher.fireActionEvent(EventDispatcher.java:257)
at com.sun.lwuit.Form.actionCommandImpl(Form.java:1115)
at com.sun.lwuit.Form.actionCommandImpl(Form.java:1090)
at com.sun.lwuit.MenuBar.actionPerformed(MenuBar.java:555)
at com.sun.lwuit.util.EventDispatcher.fireActionSync(), bci=19
at com.sun.lwuit.util.EventDispatcher.fireActionEvent(EventDispatcher.java:257)
at com.sun.lwuit.Button.fireActionEvent(Button.java:359)
at com.sun.lwuit.Button.released(Button.java:390)
at com.sun.lwuit.Button.released(Button.java:379)
at com.sun.lwuit.MenuBar.keyReleased(MenuBar.java:1211)
at com.sun.lwuit.Form.keyReleased(), bci=24
at com.sun.lwuit.Display.handleEvent(Display.java:1528)
at com.sun.lwuit.Display.edtLoopImpl(Display.java:828)
at com.sun.lwuit.Display.mainEDTLoop(Display.java:778)
at com.sun.lwuit.RunnableWrapper.run(RunnableWrapper.java:119)
at java.lang.Thread.run(), bci=11

Please help me i am not able to solve why this exception is throwing.

2 years 23 weeks ago
ernandesmjr
@ernandesmjr Ernandes Jr 

This exception is being thrown because in somehow in your code, you are calling OAuthDialogWrapper.login(String) method before OAuthDialogWrapper.login() (Invalid state: call login() method first.). The oob flow requires login() to be called first and then when you have the PIN code, you call login(String).

I hope this helps you out.

Regards,

2 years 23 weeks ago
SuyashKrSingh
@SuyashKrSingh Suyash Kumar Singh

Hi Ernandes,
every time i am getting "Error by authenticating user! " . Do i need to give some more parameter or certificates to get the access token. I am unable to lauch the Twitter login page in my nokia E5 device and because of that i am unable to get Pin Number.

2 years 23 weeks ago
ernandesmjr
@ernandesmjr Ernandes Jr 

Are you informing your consumer key and secret in the MIDlet class?

2 years 23 weeks ago
SuyashKrSingh
@SuyashKrSingh Suyash Kumar Singh

yes i am giving CONSUMER_KEY,CONSUMER_SECRET in my midlet class.I am not able to lauch the default Twitter login page. I have tested alot of Twitter integrated applications for J2me and i am getting same issue Could not find Oauth token from response: failed to validate oauth signatre and token.

2 years 23 weeks ago
ernandesmjr
@ernandesmjr Ernandes Jr 

Is the browser at least being started? Are you trying the sample app, right?

2 years 23 weeks ago
SuyashKrSingh
@SuyashKrSingh Suyash Kumar Singh

yes the browser is being started but the Twitter login page is not being displayed. I am trying with the sample app. Is there any way that i can get the pin number and login with that pin number without showing it to User and every time when i hit the Twitter Server i have to follow the same procedure getting the pin number ....

2 years 23 weeks ago
ernandesmjr
@ernandesmjr Ernandes Jr 

But anything is displayed in the browser?

Your user only need to follow this process once. As soon as he is authenticated, store the access token for forther access to apis services.

For further info about oob, read our wiki page: www.twitterapime.com

2 years 23 weeks ago
sibPutnik
@sibPutnik Ivan V. Aristov

I have the same problem on Nokia 3110c. I can't make authenticat with OAuth on Java2ME. Error report is "Failed to validate oAuth signature and token". CONSUMER_KEY and CONSUMER_SECRET a take from my apps page on twitter.

code:

  1. MIDletOAuthDialogWrapper page = new MIDletOAuthDialogWrapper(this);
  2. page.setConsumerKey(CONSUMER_KEY);
  3. page.setConsumerSecret(CONSUMER_SECRET);
  4. page.setOAuthListener(new OAuthDialogListener() {...});
  5. page.login();
2 years 23 weeks ago
SuyashKrSingh
@SuyashKrSingh Suyash Kumar Singh

i have tested the build on E5 but it is not working. it is not able to launch the browser. i think there is some issue with browser. i have seen that u are calling midlet.platformrequest(url) to launch the browser. can i use BrowserComponent of lwuit to launch the browser in that way i have more contorl over browser.

2 years 23 weeks ago
sibPutnik
@sibPutnik Ivan V. Aristov

Bug above was fixed by setting other timezone (I think, this bug is actual only for Russia).

But now I can not do anything, because after MIDletOAuthDialogWrapper.login() my App closing (browser opens) and MIDletOAuthDialogWrapper.login(PIN) never could be called.

2 years 23 weeks ago
ernandesmjr
@ernandesmjr Ernandes Jr 

I have plans to implement a LWUIT wrapper, but not so soon.

Unfortunately, this behaviour of closing the app to open the browser is known for some devices. There is nothing I can do about.

2 years 23 weeks ago
faccialive
@faccialive De La Rosa Raul

I'm sorry but I can not help in this area........

2 years 23 weeks ago
scharffc
@scharffc scharffc

Hi,
I get the following error message:
java.lang.NoClassDefFoundError: com/twitterapime/xauth/ui/TwitterAPIMEJavaMEOAuthSample: com/twitterapime/xauth/ui/OAuthDialogListener
Do you have any guidance on how to solve this?
Thanks
Christelle

2 years 18 weeks ago
mousumiatness
@mousumiatness Mousumi Khatua

I am running this app on the device and getting error :
Error by authenticating user!

2 years 10 weeks ago
sowjanyaNS
@sowjanyaNS N.S.Sowjanya

Sir i tried your code it is working fine...but remembering pin is making problem...my client is not satisfying with this procedure. That's why can you tell me some alternative for accessing twitter in case of j2me

1 year 50 weeks ago
manjeet207
@manjeet207 Manjeet Singh

No Class Def found error java/lang/NoClassDefFoundErrorcom/twitterapime/oauth/TwitterAPIMEjavaMEOAuthSample: com/twitterapime/xauth/ui/OathDialogListener

This problem occur when i execute this program on my
nokia 40 series cell phone. please help me how i can create a j2me app to post on
twitter.
Thank u.

1 year 25 weeks ago