0

我正在失去主意,试图将Facebook与应用程序整合。首先,Fb的SDK非常糟糕,并且自从我收录它以来,它的所有内容都会崩溃。无论如何,我试图从Facebook获取用户数据,只是他/她的姓名,用户ID和电子邮件;然而,我不能使用登录按钮,因为它不支持嵌套片段,它使用UiLifecycleHelper,它保持Session打开并保持执行一次回调,我只想调用一次。Android&Facebook SDK:无需登录按钮即可获取用户数据

我不需要保持Session开放;当用户第一次使用应用程序时,如果他/她想发布一些内容(非常罕见),我会零星地打开Sessions。

到目前为止,我尝试使用登录按钮,执行一个简单的请求,并结合两者。不过,整体SDK看起来与嵌套片段效果不佳。

这是我在使这项工作的最后一次尝试(这两种方法都片段内一旦按下按钮,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(); 
} 

那么,会发生什么?显示对话框提示以便使用您的Facebook帐户登录。但是,一旦你按下登录,对话框消失,什么都不会发生。 LogCat中没有显示任何内容。我认为onActivityResult方法存在问题,因为回调永远不会执行。我尝试重新添加UiLifecycleHelper,但它最终会对回调进行不必要的调用(我只想调用此方法一次)。

回答

0

因此,我设法实现了一个模块化方法来解决我的问题:我创建了一个封装到Facebook SDK的连接并通过onActivityResult返回的活动。不幸的是,我还没有找到一种方法直接将结果返回给嵌套片段。 在附注上,您可以使活动透明以避免黑屏,并在需要时添加更多权限。另外,如果要保持Session处于活动状态,则可以删除onStop方法。 这里的代码:

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(); 
    } 
} 
+0

碎片呢? – Shadow 2015-04-08 11:37:42

+0

它变成了一个巨大的混乱......由于Fb的SDK是围绕活动设计的,数据很难同步和传递。例如,SDK严重依赖于Session对象和onActivityResult;这会打破片段的数据流,并最终使用Activity作为通信中心。我的两分钱......不要尝试,最终会出现更大的问题。 – CristianGuerrero 2015-04-08 19:50:19

2

你是对的,你需要将结果传递给活动会话,以便您的回调被激活。在你的活动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); 
    } 

+0

我用它的碎片它不工作。 – Shadow 2015-04-08 11:38:22

相关问题