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

相關問題