我目前正在尝试使用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();
}
}
答案 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);
}
}