简体   繁体   English

Android和Facebook SDK:无需登录按钮即可获取用户数据

[英]Android & Facebook SDK: Obtain user data without Login Button

I am losing my mind trying to integrate Facebook with an app. 我迷失了尝试将Facebook与应用程序集成的想法。 First of all, Fb's SDK is terrible and its making everything crash since I included it. 首先,Fb的SDK非常糟糕,自从我加入它以来,一切都崩溃了。 Anyway, I am trying to obtain user data from Facebook, just his/her name, user id and email; 无论如何,我试图从Facebook获取用户数据,只是他/她的姓名,用户ID和电子邮件; however, I can't use the Login Button because it doesn't support Nested Fragments and it uses UiLifecycleHelper which keeps a Session open and keeps executing a callback that I only want to call once. 但是,我不能使用登录按钮,因为它不支持嵌套片段,并且使用UiLifecycleHelper来保持会话打开状态并继续执行我只想调用一次的回调。

I don't need to keep a Session open; 我不需要打开会话; I will sporadically open Sessions the first time the user uses the app and if he/she wants to publish something (very rare). 我会在用户首次使用该应用程序时偶尔散开会话,如果他/她想发布某些内容(非常罕见)。

So far I have tried using the Login Button, performing a simple Request and combining both. 到目前为止,我已经尝试使用“登录”按钮,执行一个简单的“请求”并将两者结合。 However, it seems that the SDK as a whole doesn't play very well with Nested Fragment. 但是,似乎SDK整体上不能与Nested Fragment配合使用。

This was my last attempt at making this work (these two methods are inside a Fragment. Once a button is pressed, performFacebookLogin is executed): 这是我做此工作的最后一次尝试(这两个方法都在Fragment中。一旦按下按钮,就会执行performFacebookLogin):

public void performFacebookLogin() {
    Session.openActiveSession(getActivity(), true, Arrays.asList("email"), new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            if (session.isOpened()) {
                Log.d("FACEBOOK", "Session has been opened");
                Request.newMeRequest(session, new Request.GraphUserCallback() {
                    @Override
                    public void onCompleted(GraphUser user, Response response) {
                        Log.d("FACEBOOK", "onCompleted");
                        if (user != null) {
                            Log.d("DBG", buildUserInfoDisplay(user));
                        }
                    }
                }).executeAsync();
            }else{
                //TODO: ERROR
                Log.e("FACEBOOK", "Session could not be opened");
            }
        }
    });
}

private String buildUserInfoDisplay(GraphUser user) {
    StringBuilder userInfo = new StringBuilder("");

    userInfo.append(String.format("Name: %s\n\n",
            user.getName()));

    userInfo.append(String.format("Email: %s\n\n",
            user.getProperty("email")));

    userInfo.append(String.format("ID: %s\n\n",
            user.getId()));

    return userInfo.toString();
}

So, what happens? 那么,会发生什么呢? The dialog prompt is shown in order to login using your Facebook account. 显示对话框提示,以便使用您的Facebook帐户登录。 But, once you press Login and the dialog disappears, nothing happens. 但是,一旦您按登录并对话框消失,则什么也不会发生。 Nothing is shown in the LogCat. LogCat中未显示任何内容。 I think is a problem with the onActivityResult method, because the callback is never executed. 我认为onActivityResult方法存在问题,因为从未执行过回调。 I tried re-adding the UiLifecycleHelper, but it ends up making unwanted calls to the callback (I only want to call this method once). 我尝试重新添加UiLifecycleHelper,但最终对回调进行了不必要的调用(我只想调用此方法一次)。

You are correct, you need to plumb the result through to the active Session for your callback to be activated. 没错,您需要将结果传递到活动会话中才能激活回调。 In your activities onActivityForResult method, call the active sessions onActivityResult, similar to this: https://github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/UiLifecycleHelper.java#L156-159 在您的活动onActivityForResult方法中,调用活动会话onActivityResult,类似于: https : //github.com/facebook/facebook-android-sdk/blob/master/facebook/src/com/facebook/UiLifecycleHelper.java#L156- 159

    Session session = Session.getActiveSession();
    if (session != null) {
        session.onActivityResult(activity, requestCode, resultCode, data);
    }

That would get your callback working. 这样可以使您的回调工作。

So, I managed to achieve a modular approach to my problem: I created an activity that encapsulated the connection to Facebook's SDK and returns it via onActivityResult. 因此,我设法实现了解决问题的模块化方法:我创建了一个活动,该活动封装了与Facebook SDK的连接,并通过onActivityResult返回。 Unfortunately, I haven't found a way to return the result to a nested fragment directly. 不幸的是,我还没有找到一种将结果直接返回到嵌套片段的方法。 On a side note, you can make the activity transparent to avoid a black screen and add more permissions if you need them. 另外,您可以使活动透明以避免黑屏,并在需要时添加更多权限。 Also, you can remove the onStop method if you want to keep the Session active. 另外,如果要保持会话活动,则可以删除onStop方法。 Here's the code: 这是代码:

public class FacebookAccessActivity extends ActionBarActivity {
public static final String PARAM_PROFILE = "public_profile";
public static final String PARAM_EMAIL = "email";
public static final String PARAM_FIRSTNAME = "fname";
public static final String PARAM_LASTNAME = "lname";
public static final String PARAM_GENDER = "gender";
public static final String PARAM_BDAY = "user_birthday";
public static final String PARAM_ID = "id";

private static Session session = null;
private List<String> permissions = Arrays.asList(PARAM_EMAIL, PARAM_PROFILE, PARAM_BDAY);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getSupportActionBar().hide();
    setContentView(R.layout.view_empty);

    session = Session.getActiveSession();

    if (session != null)
        session.closeAndClearTokenInformation();

    Session.openActiveSession(this, true, permissions, new Session.StatusCallback() {
        @Override
        public void call(Session session, SessionState state, Exception exception) {
            if (exception != null || state == SessionState.CLOSED_LOGIN_FAILED) {
                exception.printStackTrace();
                setResult(RESULT_CANCELED);
                finish();
            } else if (session.isOpened()) {
                Request.newMeRequest(session, new Request.GraphUserCallback() {
                    @Override
                    public void onCompleted(GraphUser user, Response response) {
                        if (user != null) {
                            Intent i = new Intent();
                            i.putExtra(PARAM_FIRSTNAME, user.getFirstName());
                            i.putExtra(PARAM_LASTNAME, user.getLastName());
                            i.putExtra(PARAM_ID, user.getId());
                            i.putExtra(PARAM_GENDER, (String) user.getProperty(PARAM_GENDER));
                            i.putExtra(PARAM_BDAY, user.getBirthday());

                            for (String s : permissions)
                                i.putExtra(s, (String) user.getProperty(s));
                            setResult(RESULT_OK, i);
                            finish();
                        }
                    }
                }).executeAsync();
            }
        }
    });
}

@Override
protected void onStop() {
    super.onStop();
    if (session != null)
        session.closeAndClearTokenInformation();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == RESULT_CANCELED ||
            !Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data)) {
        setResult(RESULT_CANCELED);
        finish();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM