代号为FacebookConnect

时间:2017-02-27 13:22:58

标签: codenameone

我目前正在尝试使用Codename One进行跨平台移动应用开发,该应用需要社交登录。我正在尝试介绍Facebook登录但它不起作用。我可能做错了什么?

以下是我的错误代码:

public class MyApplication {

    private Form current;
    private Resources theme;
    private String tokenPrefix;
    private String fullName;
    private String uniqueId;
    private String imageURL;
    private static EncodedImage userPlaceholder;
    private EncodedImage roundPlaceholder;

    public void start() {
        if (current != null) {
            current.show();
            return;
        }

        Form facebook = new Form(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER));
        facebook.getTitleArea().setUIID("Container");

        Button connect = new Button("Login with facebook");

        Container c = BoxLayout.encloseY(connect);

        facebook.add(BorderLayout.CENTER, c);

        connect.addActionListener((evt) -> {
            /* tokenPrefix = "facebook";
                Login fb = FacebookConnect.getInstance();
                fb.setClientId("XXXXXXXXXXXXXXXXX");
                fb.setRedirectURI("http://localhost/callback");
                fb.setClientSecret("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                doLogin(fb, new FacebookData(), false); */
            String clientId = "XXXXXXXXXXXXXXXXX";
            String redirectURI = "http://www.codenameone.com/";
            String clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
            Login fb = FacebookConnect.getInstance();
            fb.setClientId(clientId);
            fb.setRedirectURI(redirectURI);
            fb.setClientSecret(clientSecret);
            Log.p("login event triggered");
            doLogin(fb, new FacebookData(), false);
            /* if(!fb.isUserLoggedIn()){
                       doLogin(fb, new FacebookData(),false);
                    }else{
                        //get the token and now you can query the facebook API
                        String token = fb.getAccessToken().getToken();
                                      } */
        });

        facebook.show();
    }

    void doLogin(Login lg, UserData data, boolean forceLogin) {
        if (!forceLogin) {
            if (lg.isUserLoggedIn()) {
                Log.p("Fetching data......");
                showContactsForm();
                return;
            }

            String t = Preferences.get(tokenPrefix + "token", (String) null);
            if (t != null) {
                long tokenExpires = Preferences.get(tokenPrefix + "tokenExpires", (long) -1);

                if (tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) {
                    //we are still logged in 
                    Log.p("Fetching data......");
                    showContactsForm();
                    return;
                }
            }
        }
        lg.setCallback(new LoginCallback() {
            public void loginFailed(String errorMessage) {
                Log.p("Error occured");
                Dialog.show("Error Logging in", "There was an error logging in:" + errorMessage, "OK", null);
            }

            public void loginSuccessful() {
                Log.p("doLogin started");
                // when login is successful we fetch the full data
                data.fetchData(lg.getAccessToken().getToken(), () -> {
                    // we store the values of result into local variables
                    String uniqueId = data.getId();
                    String fullName = data.getName();
                    String imageURL = data.getImage();

                    // we then store the data into local cached storage so they will be around when we run the app next time
                    Preferences.set("fullName", fullName);
                    Preferences.set("uniqueId", uniqueId);
                    Preferences.set("imageURL", imageURL);
                    Preferences.set(tokenPrefix + "token", lg.getAccessToken().getToken());

                    // token expiration is in seconds from the current time, we convert it to a System.currentTimeMillis value so we can
                    // reference it in the future to check expiration
                    Preferences.set(tokenPrefix + "tokenExpires", tokenExpirationInMillis(lg.getAccessToken()));
                    showContactsForm();
                    Log.p("information fetched" + fullName + "_" + uniqueId + "_");
                });
            }
        });
        lg.doLogin();
    }

    long tokenExpirationInMillis(AccessToken token) {
        String expires = token.getExpires();
        if (expires != null && expires.length() > 0) {
            try {
                // when it will expire in seconds
                long l = (long) (Float.parseFloat(expires) * 1000);
                return System.currentTimeMillis() + l;
            } catch (NumberFormatException err) {
                // ignore invalid input
            }
        }
        return -1;
    }

    static interface UserData {

        public String getName();

        public String getId();

        public String getImage();

        public void fetchData(String token, Runnable callback);
        //  public ContactData[] getContacts();
    }

    class FacebookData implements UserData {

        String name;
        String id;
        String token;

        @Override
        public String getName() {
            return name;
        }

        @Override
        public String getId() {
            return id;
        }

        @Override
        public String getImage() {
            return "http://graph.facebook.com/v2.8/" + id + "/picture";
        }

        @Override
        public void fetchData(String token, Runnable callback) {
            this.token = token;
            ConnectionRequest req = new ConnectionRequest() {
                @Override
                protected void readResponse(InputStream input) throws IOException {
                    JSONParser parser = new JSONParser();
                    Map<String, Object> parsed = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
                    name = (String) parsed.get("name");
                    id = (String) parsed.get("id");
                }

                @Override
                protected void postResponse() {
                    callback.run();
                }

                @Override
                protected void handleErrorResponseCode(int code, String message) {
                    //access token not valid anymore
                    if (code >= 400 && code <= 410) {
                        Log.p("error occured");
                        doLogin(FacebookConnect.getInstance(), FacebookData.this, true);
                        return;
                    }
                    super.handleErrorResponseCode(code, message);
                }
            };
            req.setPost(false);
            req.setUrl("https://graph.facebook.com/v2.8/me");
            req.addArgumentNoEncoding("access_token", token);
            NetworkManager.getInstance().addToQueue(req);
        }
    }

    void showContactsForm() {

        Form result = new Form(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
        Label fname = new Label("Hello");
        Label id = new Label("Facebook");

        Container c = BoxLayout.encloseY(fname, id);

        fname.setText(Preferences.get("fullName", fullName));
        id.setText(Preferences.get("uniqueId", uniqueId));

        result.add(BorderLayout.CENTER, c);
        result.show();
    }
}

1 个答案:

答案 0 :(得分:3)

首先,确保在Facebook开发者控制台上正确设置了您的Facebook登录信息。

以下是获取所需信息的方法:

请注意这一行 req.addArgumentNoEncoding("fields", "id,email,name,first_name,last_name,gender,age_range,picture.width(512).height(512),locale,link,timezone,updated_time");我们告诉Facebook我们需要哪些信息

我使用Dialog检查processFacebookLogin()中的输出是否有调试目的,而不是showContact()

void doLogin(Login lg, UserData data, boolean forceLogin) {
    if (!forceLogin) {
        if (lg.isUserLoggedIn()) {
            processFacebookLogin(data);
            return;
        }

        // if the user already logged in previously and we have a token
        String token = Preferences.get(tokenPrefix + "token", (String) null);
        if (getToolbar() != null) {
            // we check the expiration of the token which we previously stored as System time
            long tokenExpires = Preferences.get(tokenPrefix + "tokenExpires", (long) -1);
            if (tokenExpires < 0 || tokenExpires > System.currentTimeMillis()) {

                data.fetchData(token, () -> {
                    processFacebookLogin(data);
                });
                return;
            }
        }
    }

    lg.setCallback(new LoginCallback() {
        @Override
        public void loginFailed(String errorMessage) {
            Dialog.show("Error Logging In", "There was an error logging in with Facebook: " + errorMessage, "Ok", null);
        }

        @Override
        public void loginSuccessful() {
            data.fetchData(lg.getAccessToken().getToken(), () -> {
                Preferences.set(tokenPrefix + "token", lg.getAccessToken().getToken());
                Preferences.set(tokenPrefix + "tokenExpires", tokenExpirationInMillis(lg.getAccessToken()));
                processFacebookLogin(data);
            });
        }
    });
    lg.doLogin();
}

long tokenExpirationInMillis(AccessToken token) {
    String expires = token.getExpires();
    if (expires != null && expires.length() > 0) {
        try {
            // when it will expire in seconds
            long l = (long) (Float.parseFloat(expires) * 1000);
            return System.currentTimeMillis() + l;
        } catch (NumberFormatException err) {
            // ignore invalid input
        }
    }
    return -1;
}


class FacebookData implements UserData {

    String id;
    String email;
    String name;
    String first_name;
    String last_name;
    String image;
    String link;
    String gender;
    String locale;
    Double timezone;
    String updated_time;
    String verified;

    @Override
    public String getId() {
        return id;
    }

    @Override
    public String getEmail() {
        return email;
    }

    @Override
    public String getFullName() {
        return name;
    }

    @Override
    public String getFirstName() {
        return first_name;
    }

    @Override
    public String getLastName() {
        return last_name;
    }

    @Override
    public String getGender() {
        return gender;
    }

    @Override
    public String getLink() {
        return link;
    }

    @Override
    public String getLocale() {
        return locale;
    }

    @Override
    public Double getTimezone() {
        return timezone;
    }

    @Override
    public String getUpdatedTime() {
        return updated_time;
    }

    @Override
    public String getImage() {
        return image;
    }

    @Override
    public void fetchData(String token, Runnable callback) {
        ConnectionRequest req = new ConnectionRequest() {
            @Override
            protected void readResponse(InputStream input) throws IOException {
                JSONParser parser = new JSONParser();
                Map<String, Object> parsed = parser.parseJSON(new InputStreamReader(input, "UTF-8"));
                id = (String) parsed.get("id");
                email = (String) parsed.get("email");
                name = (String) parsed.get("name");
                first_name = (String) parsed.get("first_name");
                last_name = (String) parsed.get("last_name");
                link = (String) parsed.get("link");
                gender = (String) parsed.get("gender");
                locale = (String) parsed.get("locale");
                timezone = (Double) parsed.get("timezone");
                updated_time = (String) parsed.get("updated_time;");
                verified = (String) parsed.get("verified");
                image = (String) ((Map) ((Map) parsed.get("picture")).get("data")).get("url").toString();
            }

            @Override
            protected void postResponse() {
                callback.run();
            }

            @Override
            protected void handleErrorResponseCode(int code, String message) {
                //access token not valid anymore
                if (code >= 400 && code <= 410) {
                    doLogin(FacebookConnect.getInstance(), FacebookData.this, true);
                    return;
                }
                super.handleErrorResponseCode(code, message);
            }
        };
        req.setPost(false);
        req.setUrl("https://graph.facebook.com/v2.8/me");
        req.addArgumentNoEncoding("access_token", token);
        req.addArgumentNoEncoding("fields", "id,email,name,first_name,last_name,gender,age_range,picture.width(512).height(512),locale,link,timezone,updated_time");
        NetworkManager.getInstance().addToQueue(req);
    }
}