安卓Facebook授权 - 当官方Facebook应用程序已安装时无法登录

10

我需要登录Facebook并获取像电子邮件等相同的字段。我使用Facebook SDK,并在developers.facebook中设置了我的Android密钥哈希,并设置“配置为Android SSO”。在模拟器和某些设备上,应用程序可以正常工作。

但是,如果设备上安装了官方Facebook应用程序,则我的应用程序将无法工作:我按下登录按钮,但是我没有看到一个包含Web视图的对话框,要求我输入密码和登录信息。这似乎与Stack Overflow问题“Using facebook.authorize with the Android SDK does not call onActivityResult”或Stack Overflow问题“Android Facebook API single sign-on?”有关,但我不知道如何解决它。

我的代码

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    this.facebookConnector.getFacebook().authorizeCallback(requestCode, resultCode, data);
}

public void getAccessToken() {
    SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {
        @Override
        public void onAuthSucceed() {
            setupAccessToken(facebookConnector.getFacebook().getAccessToken());
        }

        @Override
        public void onAuthFail(String error) {
            Toast.makeText(getApplicationContext(), getString(R.string.error_login), Toast.LENGTH_SHORT).show();
        }
    };

    SessionEvents.addAuthListener(listener);
    facebookConnector.login();
}

Facebook连接器代码

public class FacebookConnector {
    public void login() {
        if (!facebook.isSessionValid()) {
            facebook.authorize(this.activity, this.permissions, new LoginDialogListener());
        }
    }

    private final class LoginDialogListener implements DialogListener {
        public void onComplete(Bundle values) {
            SessionEvents.onLoginSuccess();
        }

        public void onFacebookError(FacebookError error) {
            SessionEvents.onLoginError(error.getMessage());
        }

        public void onError(DialogError error) {
            SessionEvents.onLoginError(error.getMessage());
        }

        public void onCancel() {
            SessionEvents.onLoginError("Action Canceled");
        }
    }
}

如果您正在使用Facebook登录集成,可以请检查一下这个链接并告诉我哪里出了问题:http://stackoverflow.com/questions/11293815/how-to-ignore-facebook-android-application-installed-on-the-device-when-using-a。或者,请粘贴您的应用程序的工作代码。 - Archie.bpgc
4个回答

20
请更新您应用程序中的以下代码。它会解决您的问题。
public void loginAndPostToWall() {
    facebook.authorize(this, PERMISSIONS, Facebook.FORCE_DIALOG_AUTH,
            new LoginDialogListener());
}

如果我们更改Facebook密码并检查请求是否为“me”,如果出现错误,则打开Facebook登录对话框,但是如果我们再次检查“me”请求时仍然显示错误,那么为什么会话令牌没有被替换? - SRam
但是 Dipak,你认为这是一个万无一失的解决方案吗?难道 SDK 不应该从设备上安装的 Facebook 应用程序获取会话吗? - Nitesh Verma

5

我和你有同样的问题。最终,我使用以下方法解决了这个问题:

打开Facebook SDK提供的Facebook.java文件,然后进行如下更改:

public void authorize(Activity activity, String[] permissions,
                      int activityCode, final DialogListener listener) {
    boolean singleSignOnStarted = false;

    mAuthDialogListener = listener;

    /*
    // Prefer single sign-on, where available.
    if (activityCode >= 0) {
        singleSignOnStarted = startSingleSignOn(activity, mAppId,
                                                permissions, activityCode);
    }
    // Otherwise fall back to the traditional dialog.
    if (!singleSignOnStarted) {
    */

    startDialogAuth(activity, permissions);

    // }
}

没有必要更改 Facebook 代码,应该可以在不进行黑客攻击的情况下正常工作。这不是一个好的做法,因为 Facebook 可能明天就会更改他们的代码,然后当你更新自己的代码库时,你需要记住所有你所做的更改。 - Nitzan Tomer
谢谢你的回答,很有用,但是@Dipak Keshariya的代码以更正确的方式完成了相同的任务。 - anber

1

这只是一个猜测,但不妨试试这个:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    this.facebookConnector.getFacebook().authorizeCallback(requestCode, resultCode, data);
}

尝试:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    this.facebookConnector.getFacebook().authorizeCallback(requestCode, resultCode, data);
}

由于您没有调用父方法,某些功能可能无法按预期工作...


0
private static Session openActiveSession(Activity activity, boolean allowLoginUI, StatusCallback callback, List<String> permissions) {
    OpenRequest openRequest = new OpenRequest(activity).setPermissions(permissions).setLoginBehavior(SessionLoginBehavior.SUPPRESS_SSO).setCallback(callback);
    Session session = new Session.Builder(activity).build();
    if (SessionState.CREATED_TOKEN_LOADED.equals(session.getState()) || allowLoginUI) {
        Session.setActiveSession(session);
        session.openForRead(openRequest);
        return session;
    }
    return null;
}

请将您的openactivesession函数修改为以下内容


我尝试了你的代码Jossy,似乎不能打开对话框。 - Vny Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接