Android Facebook SDK 4.0无需Facebook应用程序登录

14

我在Android上使用Facebook的webview登录时遇到了问题。

我按照教程操作,当用户安装了Facebook应用程序时,登录工作正常。但是,如果没有安装Facebook应用程序,则会弹出Facebook登录的webview;但是,在登录并接受权限后,webview只会简单地重定向回登录屏幕。它从未返回到我的应用程序。

有其他人遇到过这个问题吗?

    FacebookSdk.sdkInitialize(this);
    profileTracker = new ProfileTracker() {
        @Override
        protected void onCurrentProfileChanged(Profile profile, Profile profile2) {
            if (profile2 != null) {
                loggedIn(profile2);
            } else {
                loggedOut();
            }
        }
    };
    accessTokenTracker = new AccessTokenTracker() {
        @Override
        protected void onCurrentAccessTokenChanged(AccessToken accessToken, AccessToken accessToken2) {
            Profile.fetchProfileForCurrentAccessToken();
        }
    };
    callbackManager = CallbackManager.Factory.create();
    LoginManager.getInstance().registerCallback(callbackManager,
            new FacebookCallback<LoginResult>() {
                @Override
                public void onSuccess(LoginResult loginResult) {
                    // App code
                    getProfileInfo();
                }

                @Override
                public void onCancel() {
                    // App code
                    Log.e("Facebook Login", "Login Cancelled");
                    loggedOut();
                }

                @Override
                public void onError(FacebookException exception) {
                    // App code
                    Log.e("Facebook Login", "Failed to Login " + exception.toString());
                    loggedOut();
                }
            });

在登录过程中查看没有筛选器的日志,我看到了几个可能相关的日志。

I/chromium﹕ [INFO:CONSOLE(0)] "event.returnValue is deprecated. Please use the standard event.preventDefault() instead.", source:  (0)
I/Auth.Core﹕ [TokenCache] Missing snowballing token: no granted scopes set.

@HunterFrazier:无效的重定向URI应该在用户接受权限之前就会导致错误消息。 - CBroe
我非常确定这与代码无关,但我还是会发布它。这是来自新Facebook SDK的标准登录代码。如果用户有Facebook应用程序,则登录工作正常。只有当用户通过Web登录时才会出现问题。它甚至从未进入onActivityResult。 - sihrc
我刚试了一下,只看到了几个可能相关的日志(很难确定)。我会在我的问题中更新。 - sihrc
对我来说,我的问题是在点击按钮时覆盖按钮并通过管理器手动调用登录。如果你还有问题,我不介意看一下! - sihrc
@sihrc 感谢您的提供。我所做的是回到我们应用程序的实时版本,只是为了看看是否有我更改的内容,因为我100%确定它以前是可以工作的。但是现在也不起作用。就好像Facebook打开的对话框上发生了一些变化。完全相同的代码以前都能正常工作。 - Roberto
显示剩余7条评论
4个回答

5

我认为您忘记使用callbackManager以获得正确的工作流程。在宿主活动的onActivityResult中调用注册回调,必须使用CallbackManager。活动不应该处于singleInstance launchMode,因为它将无法启动startActivityForResult(Facebook在内部使用此方法启动FacebookActivity)。 因此,请将以下内容添加到您的活动中:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    callbackManager.onActivityResult(requestCode, resultCode, data);
}

5

问题的原因是我覆盖了登录按钮的onclicklistener,以调用LoginManager的登录函数。请不要这样做。


嘿,我找到了原因,但是去掉 @Override 对我没有用。 - iamabhaykmr

3
根据您的描述,我想象您可能没有连接互联网或者没有处理登录回调。
这里有一个完整的facebook 4.0.+登录示例
根据您的代码进行编辑:
setContentView()之前,您需要使用FacebookSdk.sdkInitialize(this);

1
这是一个不使用Facebook应用程序的工作示例,如果您关闭应用程序并再次打开它,您将自动登录,除非您退出登录。在此,我们在登录后获取用户电子邮件地址和好友列表。
public class MainActivity extends Activity {

    private CallbackManager callbackManager;
    private LoginButton loginButton;
    private static final String TAG = "logTag";
    private TextView mFriend, mEmail;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FacebookSdk.sdkInitialize(getApplicationContext());
        callbackManager = CallbackManager.Factory.create();

        setContentView(R.layout.activity_main);
        mFriend = (TextView) findViewById(R.id.tv_friend);
        mEmail = (TextView) findViewById(R.id.tv_email);

        loginButton = (LoginButton) findViewById(R.id.login_button);
        loginButton.setReadPermissions(Arrays.asList("public_profile, email, user_birthday, user_friends"));
        loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
            @Override
            public void onSuccess(LoginResult loginResult) {
                Log.d(TAG, "Successful Login");
                GraphRequest friendsRequest = GraphRequest.newMyFriendsRequest(
                        loginResult.getAccessToken(),
                        new GraphRequest.GraphJSONArrayCallback() {
                            @Override
                            public void onCompleted(JSONArray objects, GraphResponse response) {


                                String x = objects.opt(0).toString();
                                mFriend.setText(x);

                            }
                        });
                GraphRequest meRequest = GraphRequest.newMeRequest(
                        loginResult.getAccessToken(),
                        new GraphRequest.GraphJSONObjectCallback() {
                            @Override
                            public void onCompleted(JSONObject object, GraphResponse response) {
                                try {
                                    String email = response.getJSONObject().getString("email").toString();
                                    mEmail.setText(email);
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }

                            }
                        });

                Bundle parameters = new Bundle();
                parameters.putString("fields", "id, name, email, gender");
                meRequest.setParameters(parameters);
                meRequest.executeAsync();

                parameters = new Bundle();
                parameters.putString("field", "user_friends");
                friendsRequest.setParameters(parameters);
                friendsRequest.executeAsync();

            }

            @Override
            public void onCancel() {
                Log.d(TAG, "Login Canceled");
            }

            @Override
            public void onError(FacebookException error) {
                Log.d(TAG, "Login Error");
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        super.onActivityResult(requestCode, resultCode, data);
        // manage login results
        callbackManager.onActivityResult(requestCode, resultCode, data);
    }
}

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