LoginManager: A Facebook & Google Login Helper for Android

Hey I guys, I’d like to make this humble contribution to this great community.
Before introducing this, you must know: this is a one-week-work, and a work-in-progress. This isn’t finished, and I don’t recommend using this as it is right now in any release project. And I’m spanish speaker, so sorry for my mistakes when writing in English.

The LoginManager is a sort-of-library that I’m working on. Right know it handles Facebook Login/out and (some) extra Facebook permissions can be requested too. Soon, it will extend to handle Google login too.

It requires you to be a Facebook Developer, have a Facebook app, and always run a signed apk.
I really recommend that if you are willing to test this as it is right now, do it at an empty project!!

You can log-in an user at any time of the game, and get this user data into your game.

How the lib works? (from the wiki) The lib just provides the communication between your jMe project and the Facebook SDK. The actual login is done by Facebook. Whenever you want to log-in an user, you just have to call FacebookManager.login(), and the Facebook LoginActivity will launch, if it's the first time the user logs in with your app, it will ask for the already setted Facebook Permissions, if not, it will just log-in. Then, it will go back to your game with the current user data inside a FaebookUser instance.

Please feel free to check the repo. There’s a tutorial about the setup in the wiki if you wanna test this. As I’ve said, I do not recommend to use this at any release project. But, obviously this is open source, so you can just grab this and improve it (at your own risk) to make your own login as you please.

Let me know what you think! And if someone is willing to test this, and follows the tutorials in the Wiki, let me know how that goes, couse I’m not particulary good at writing tutorials I belive.

1 Like

This is awesome! Once this is finished up, your sheer brilliance will save me countless weeks of ripping my hair out and swearing at companies that could care less about my woes :wink:

1 Like
@turco.chaia said: This isn't finished, and I don't recommend using this as it is right now in any release project.

Only smart people listen to warnings like this… so I should have this integrated into all my apps within the hour =P

@t0neg0d said: This is awesome! Once this is finished up, your sheer brilliance will save me countless weeks of ripping my hair out and swearing at companies that could care less about my woes ;)

Luckily it will @t0neg0d! I hope it does someday!

@t0neg0d said: Only smart people listen to warnings like this... so I should have this integrated into all my apps within the hour =P

Lol, I really wouldn’t recommend you doing so! :oops:

1 Like

Login when clicking on a button. Using TonegodGUI. You must follow the tutorial for this to work.

[java]
package mygame;

import com.ar.lchproducciones.loginmanager.core.FacebookLocation;
import com.ar.lchproducciones.loginmanager.core.FacebookUser;
import com.ar.lchproducciones.loginmanager.core.HarnessListener;
import com.jme3.app.SimpleApplication;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.Vector2f;
import com.jme3.renderer.RenderManager;
import tonegod.gui.controls.buttons.Button;
import tonegod.gui.controls.buttons.ButtonAdapter;
import tonegod.gui.controls.text.Label;
import tonegod.gui.controls.windows.Panel;
import tonegod.gui.controls.windows.Window;
import tonegod.gui.core.Element;
import tonegod.gui.core.Screen;

public class Main extends SimpleApplication {

private HarnessListener harnessListener;
private FacebookUser facebookUser = null;
/* TonegodGUI */
private Screen screen;
private Window window;
private Panel userDataPanel;
private Button button;

public static void main(String[] args) {
    Main app = new Main();
    app.start();
}

@Override
public void simpleInitApp() {
    initGUI();
}

public HarnessListener getHarnessListener() {
    return harnessListener;
}

public void setHarnessListener(HarnessListener harnessListener) {
    this.harnessListener = harnessListener;
}

@Override
public void simpleUpdate(float tpf) {
    //Note that since the login progress is done asynchronously, the FacebookUser may not be setted right after calling login(), that's why the
    //facebookUser is asigned inside the simpleUpdate() and obviously should be run only once!
    if (harnessListener.getFacebookUser() != null && facebookUser == null) {
        facebookUser = harnessListener.getFacebookUser();
        updateWindow();
    }
}

/* TonegodGUI */
private void initGUI() {
    screen = new Screen(this, "tonegod/gui/style/atlasdef/style_map.gui.xml");
    screen.setUseTextureAtlas(true, "tonegod/gui/style/atlasdef/atlas.png");
    screen.setUseMultiTouch(true);
    guiNode.addControl(screen);
    screen.setUseKeyboardIcons(true);
    screen.setUseCustomCursors(false);

    window = new Window(screen, new Vector2f(20, (screen.getHeight() / 3)),
            new Vector2f(screen.getWidth() - 40, screen.getHeight() / 2));
    window.setWindowTitle("Welcome, please log in");
    screen.addElement(window);

    userDataPanel = new Panel(screen, new Vector2f(15, 40), new Vector2f(window.getWidth() - 30, window.getHeight() - 50));
    window.addChild(userDataPanel);

    button = new ButtonAdapter(screen, new Vector2f(window.getWidth() * 0.70f, window.getHeight() * 0.70f)) {
        @Override
        public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
            if (harnessListener != null) {
                harnessListener.facebookLogin();
                button.setIsEnabled(false);
            }
        }
    };
    button.setText("Log In");
    window.addChild(button);
}

private void addLabel(String text, Element e, Vector2f pos) {
    Label label = new Label(screen, pos, new Vector2f(userDataPanel.getWidth(), 30));
    label.setText(text);
    e.addChild(label);
}

private void updateWindow() {
    Vector2f pos = new Vector2f(15, 50);
    int padding = 25;
    /* Getting the User Data */
    window.setWindowTitle("Welcome " + facebookUser.getFirstName());
    addLabel(facebookUser.getFullName() + " FID> " + facebookUser.getId(), userDataPanel, pos);
    pos.y += padding;
    addLabel(facebookUser.getUsername() + " " + facebookUser.getBirthday(), userDataPanel, pos);
    pos.y += padding;
    addLabel(" URL " + facebookUser.getLink(), userDataPanel, pos);
    pos.y += padding;
    FacebookLocation location = facebookUser.getLocation();
    if (location != null) {
        addLabel(location.getFormatedLocation(), userDataPanel, pos);
    }

}

}
[/java]

1 Like

A question/suggestion about the example above:

Since the calls are asynchronous, it may be better to enqueue the request as a Future to keep things simple… and common as features are added.

I also had a second question:

In what format (format is a bad choice of words… ) does FaceBook’s API stream images? Image? Or?

@t0neg0d said: A question/suggestion about the example above:

Since the calls are asynchronous, it may be better to enqueue the request as a Future to keep things simple… and common as features are added.

I also had a second question:

In what format (format is a bad choice of words… ) does FaceBook’s API stream images? Image? Or?

Great Idea @t0neg0d! Thank you very much.
About Images…
Im working on getting the user’s profile picture, but, belive it or not, It’s giving me more troubles than I thought. Since this in Android, ImageIO doesn’t exist (in case you didn’t know), you must use BitmapImage, which is optimized for Android. The thing is, I’ve absolutly no Idea how to load a BitmapImage into the Asset Manager.
Other idea I had is, since every profile picture has an unique URL which is something like http://graph.facebook.com/USER_ID/picture. I thought I could use the UrlLoader module of the AssetManager to load the picture… The thing is, I don’t know the name of the picture, and It changes depending on the user.
It’d be faster to just load the image from the web using an AsyncTask, than making a request to the FB API to get the picture id, and then load it into android as BitmapImage…
Any idea about this?

@turco.chaia said: Great Idea @t0neg0d! Thank you very much. About Images.. Im working on getting the user's profile picture, but, belive it or not, It's giving me more troubles than I thought. Since this in Android, ImageIO doesn't exist (in case you didn't know), you must use BitmapImage, which is optimized for Android. The thing is, I've absolutly no Idea how to load a BitmapImage into the Asset Manager. Other idea I had is, since every profile picture has an unique URL which is something like http://graph.facebook.com/USER_ID/picture. I thought I could use the UrlLoader module of the AssetManager to load the picture.. The thing is, I don't know the name of the picture, and It changes depending on the user. It'd be faster to just load the image from the web using an AsyncTask, than making a request to the FB API to get the picture id, and then load it into android as BitmapImage.. Any idea about this?

Only other thought I have on the image would be to open it on the App side as an Image > Texture2D (instead of BitmapImage) that can be pushed to a shader for rendering in the JME scene (ui… or whatever).

Sooo… um…

Future send request for profile image
Image is streamed back and read in as an AWT Image.
Create a Texture2D with this Image as it backing data
Return the Texture2D as the results of the Future (which was originally enqueued via the JmeToHarness call)
Giving your app a new Texture to load directly into a Material.

I have ZERO clue how iOS works and am a bit confused by @normen 's last post… buuuut… will go do some reading. The reason I’m tagging him is he may have some input on whether or not UrlLoader will work for iOS apps. I know that iOS is stand-off-ish when it comes to access to directories/files/etc. But I don’t know how encompassing that is and whether or not that includes http requests (I doubt it does… but better to have someone who knows answer this).

@t0neg0d said: Only other thought I have on the image would be to open it on the App side as an Image > Texture2D (instead of BitmapImage) that can be pushed to a shader for rendering in the JME scene (ui... or whatever).

Sooo… um…

Future send request for profile image
Image is streamed back and read in as an AWT Image.
Create a Texture2D with this Image as it backing data
Return the Texture2D as the results of the Future (which was originally enqueued via the JmeToHarness call)
Giving your app a new Texture to load directly into a Material.

I have ZERO clue how iOS works and am a bit confused by @normen 's last post… buuuut… will go do some reading. The reason I’m tagging him is he may have some input on whether or not UrlLoader will work for iOS apps. I know that iOS is stand-off-ish when it comes to access to directories/files/etc. But I don’t know how encompassing that is and whether or not that includes http requests (I doubt it does… but better to have someone who knows answer this).

That looks promising! I’ll let you know how it goes. It’s nice to get some help with this! Thank you mate.

To be honest, I’ve absolutly no idea about iOs. I’ve seen a few iOS devices in my entire life LOL.
So, I’ve really never intersted in learning to code for those expensive little things. So, obviously I won’t be able to test this in iOS, nor know how to fix iOS-exclusive issues. (btw, I don’t really like how this last sentence sounds, I hope you get what I mean).
Thanks again!

@turco.chaia said: That looks promising! I'll let you know how it goes. It's nice to get some help with this! Thank you mate.

To be honest, I’ve absolutly no idea about iOs. I’ve seen a few iOS devices in my entire life LOL.
So, I’ve really never intersted in learning to code for those expensive little things. So, obviously I won’t be able to test this in iOS, nor know how to fix iOS-exclusive issues. (btw, I don’t really like how this last sentence sounds, I hope you get what I mean).
Thanks again!

Soon(ish) I’ll be grabbing what I need to start testing for iOS. Once I do, I’ll try and be as much help as I can. I’ll likely just have to ask other people who really know :wink: But, I can at least test and help track down problem areas/possible solutions.

@t0neg0d said: Soon(ish) I'll be grabbing what I need to start testing for iOS. Once I do, I'll try and be as much help as I can. I'll likely just have to ask other people who really know ;) But, I can at least test and help track down problem areas/possible solutions.

That’s great!! Baby steps they say, baby steps.
Luckily it’ll be sooner than you think.
Hey, about the images, I was thinking, don’t really know to be honest. Maybe it’d be better to use an Android AsyncTask for loading the images? I’d say it should be improved for Android, just a guess though.
I’m wonder how long it’d take to load some pictures (i.e: (part of ) friend list) when using 3G.

Now that I’m thinking, the Facebook SDK includes an Android widget called com.facebook.widget.ProfilePictureView. Obviously this is supposed to be used in an Android XML Layout, but It’d be interesting to see how they get the pictures. Gonna check it out

EDIT: BTW, I think awt.Image isn’t included in Android!

1 Like
@turco.chaia said: That's great!! Baby steps they say, baby steps. Luckily it'll be sooner than you think. Hey, about the images, I was thinking, don't really know to be honest. Maybe it'd be better to use an Android AsyncTask for loading the images? I'd say it should be improved for Android, just a guess though. I'm wonder how long it'd take to load some pictures (i.e: (part of ) friend list) when using 3G.

Now that I’m thinking, the Facebook SDK includes an Android widget called com.facebook.widget.ProfilePictureView. Obviously this is supposed to be used in an Android XML Layout, but It’d be interesting to see how they get the pictures. Gonna check it out.

Once the general idea is together, you could provide both with a line or 3 of code. nehon’s last release was a mixture of Activity-based android app with portions that use JME.

@turco.chaia said: EDIT: BTW, I think awt.Image isn't included in Android!

I may not have meant awt… sorry!!

1 Like
@t0neg0d said: Once the general idea is together, you could provide both with a line or 3 of code. nehon's last release was a mixture of Activity-based android app with portions that use JME.
If you mean I could provide both (in-jMe and Activities), that's no problem. I mean, doing it with Activities isn't really hard, Facebook is beautifully documented, and they provide (android) widgets for almost everything (like friend list, profile pic, albums, news feed etc), I could even use the same FacebookManager for both. I think the most important thing at the moment is being able to get all that data into jMe, and into activities using the same Manager (FacebookManager in this case). That's why I wanna keep that class only with android code, so It's not jMe dependant. Also the LoginManager Android project, doesn't include jMe libs. And the LoginManager jMe project, doesn't include the Android libs. I'm not sure if this is the best aproach, but it sure looks pretty cool for now.
@turco.chaia said: Facebook is beautifully documented, and they provide (android) widgets for almost everything (like friend list, profile pic, albums, news feed etc),

Someone needs to tell Google to hire Facebook developers to come sort out their abortion of an API (Google Play Services… it should have been name Google Plague Services) =P

@t0neg0d said: Someone needs to tell Google to hire Facebook developers to come sort out their abortion of an API (Google Play Services... it should have been name Google Plague Services) =P
Hhahah, lol men, Google Plague Services, that was really funny.
1 Like