2

我切換從Activity某些Android Facebook的代碼爲Fragment。在切換之前一切正常,但現在onComplete()回調沒有被執行。爲什麼Android Facebook界面不能使用Fragments?

Facebook代碼不能與片段,還是我做錯了什麼?

這裏的原代碼(在SherlockActivity):

if (!mFacebook.isSessionValid()) { 
    mFacebook.authorize(MyActivity.this, permissions, new DialogListener() { 
     @Override 
     public void onComplete(Bundle values) { ... } // CALLED AS EXPECTED 
    } 
} 

而這裏的新代碼(在SherlockFragment):

if (!mFacebook.isSessionValid()) { 
    mFacebook.authorize(getActivity(), permissions, new DialogListener() { 
     @Override 
     public void onComplete(Bundle values) { ... } // DOES NOT GET CALLED 
    } 
} 

的活性和分片包括相同的onActivityResult( )根據Facebook的要求:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    mFacebook.authorizeCallback(requestCode, resultCode, data); 
} 

感謝您的幫助!

編輯:一個類似的問題被要求here,其中接受的答案是將Fragment更改爲FragmentActivity。但我不明白這有什麼幫助,因爲它不再是Fragment(我需要其他原因)。建議?

編輯2:我推出了我自己的解決方案。見下文。

回答

12

至於我能確定,Facebook的身份驗證API不支持片段。具體而言,從Facebook的authorize()呼叫onComplete()回調可與活動,但不能與片段

所以我把一個簡單的解決方法片段。該解決方案依賴於一個事實,即onActivityResult()也被稱爲父活動authorize()調用完成時,所以你可以用它來建立一個獨立的回調機制,爲片段

首先,建立在父變量活動進行目標片段的名字,說

TargetFragment mTargetFragment; 

可以初始化它的時候,這個片段第一實例是這樣的:

@Override 
public void onAttachFragment(Fragment fragment) { 
    super.onAttachFragment(fragment); 

    String fragmentSimpleName = fragment.getClass().getSimpleName(); 

    if (fragmentSimpleName.equals("TargetFragment")) 
     mTargetFragment = (TargetFragment)fragment;   
} 

然後將幾行添加到onActivityResult()函數中:

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

    if (mTargetFragment != null)  
     mTargetFragment.myCallBack(requestCode, resultCode, data); 
} 

現在你可以模仿你通常會放入的onComplete()回調在新myCallBack函數()函數的代碼:我希望這可以幫助別人

public void myCallBack(int requestCode, int resultCode, Intent data) { 
    mFacebook.authorizeCallback(requestCode, resultCode, data); 

    // other code from your onComplete() function ... 
} 

。乾杯!

+0

Sooo help!感謝您查看這個! – ByteMe

+0

嗨 我正在嘗試這個解決方案,但是我在myCallback函數中的facebook.authorizeCallback上得到了一個N​​etworkOnMainThreadException。 謝謝! –

+0

我不確定authorizeCallback()實際上是否執行網絡事務,但如果是這樣,您需要將它從任何面向用戶的Activity移出(使用類似AsyncTask的東西)。這是因爲Android具有嚴格的模式,可以阻止面向用戶的線程執行網絡事務。對於快速開發的解決方法,可以在Activity的onCreate()調用中放入以下兩行:StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()。permitAll()。build(); StrictMode.setThreadPolicy(policy);確保在生產之前刪除解決方法並進行修復。祝你好運! – gcl1

5

我已經下載了最新版本的Facebook SDK和我有同樣的問題,的gcl1解決工作正常,但我必須做的活動成果更多的事情,所以我作出這個父活動:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (mTargetFragment != null) { 
     mTargetFragment.onActivityResult(requestCode, resultCode, data); 
    } 
} 
2

Facebook SDK不能與Fragment一起使用,但可以與FragmentActivity一起使用。 所以你需要:

  1. 在父FragmentActivity的onActivityResult()中捕獲FB登錄信息。
  2. 傳遞活動的結果對你的孩子片段

例如:

1.

public class MainActivity extends FragmentActivity(){ 


/* catch FACEBOOK login info and call onFBLoginActivityResult() to pass it to FacebookFrragment*/ 
    @Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) { 
     super.onActivityResult(requestCode, resultCode, data); 

     android.support.v4.app.FragmentManager fm = getSupportFragmentManager(); 
     FacebookFragment fbfragment= (FacebookFragment) fm.findFragmentByTag("facebookfragment"); 
     selectPKEConfigFragment.onFBLoginActivityResult(requestCode, resultCode, data); 

    } 

} 

2.

public class FacebookFragment extends Fragment{ 

     @Override 
      public View onCreateView(LayoutInflater inflater, ViewGroup container, 
       Bundle savedInstanceState) { 
     // ........... 

     // start Facebook Login 

        Session.openActiveSession(getActivity(), true, new Session.StatusCallback() { 

         // callback when session changes state 
         @Override 
         public void call(Session session, SessionState state, Exception exception) { 
         if (session.isOpened()) { 
          // make request to the /me API 
          Request.executeMeRequestAsync(session, new Request.GraphUserCallback() { 

          // callback after Graph API response with user object 
          @Override 
          public void onCompleted(GraphUser user, Response response) { 
           if (user != null) { 
           // TextView welcome = (TextView) findViewById(R.id.welcome); 
           // welcome.setText("Hello " + user.getName() + "!"); 
            Log.i(TAG,"User: " + user.getName()); 
           } 
           else Log.i(TAG,"User: null"); 
          } 
          }); 
         } 
         else Log.i(TAG,"session closed"); 
         } 


        }); 

      } 

     /* 
     * replace onActivityResult 
     */ 
     public void onFBLoginActivityResult(int requestCode, int resultCode, Intent data){ 
      Log.i(TAG,"Activity result SelectPKEConfig"); 
      Session.getActiveSession().onActivityResult(getActivity(), requestCode, resultCode, data); 
     } 
0

我們並不需要配置onActivityResult內主片段類和片段內的活動。 只需將下面的代碼放在包含您的片段的主要活動內部,並在片段內部完成facebook sdk代碼的其餘部分...其過程非常簡單。

@Override 
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    { 
     super.onActivityResult(requestCode, resultCode, data); 
     Session.getActiveSession().onActivityResult(ChatScreen.this, requestCode, 
       resultCode, data); 
    } 
1

其實,如果你看看Facebook Docs for Android你會看到登錄示例使用片段吧。

有Facebook SDK提供的LoginButton小部件,它有一個名爲setFragment的方法,並且您傳遞了要使用登錄功能的目標片段。

在你的片段佈局

添加登錄按鈕,Facebook的SDK提供。

 <com.facebook.widget.LoginButton 
      android:id="@+id/facebook_login_button" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_gravity="center_horizontal" 
      android:layout_marginTop="30dp" /> 

在您的片段

創建UiLifecycleHelper並在片段StatusCallback對象。

private UiLifecycleHelper uiHelper; 
private Session.StatusCallback callback = new Session.StatusCallback() { 
    @Override 
    public void call(Session session, SessionState state, Exception exception) { 
     onSessionStateChange(session, state, exception); 
    } 
}; 

添加處理用戶狀態更改的方法。

private void onSessionStateChange(Session session, SessionState state, Exception exception) { 
    if (state.isOpened()) { 
     Log.i("LoginFragment", "Logged in..."); 
     Log.i("LoginFragment", session.getAccessToken()); 
     doAnythingWithTheFacebookToken(session.getAccessToken()); 
    } else if (state.isClosed()) { 
     // this part is called when user login fails 
     Log.i("LoginFragment", "Logged out..."); 
    } 
} 

覆蓋片段生命週期方法

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    uiHelper = new UiLifecycleHelper(getActivity(), callback); 
    uiHelper.onCreate(savedInstanceState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

    // inflate your fragment view 

    facebookLoginButton = (LoginButton) view.findViewById(R.id.facebook_login_button); 
    facebookLoginButton.setFragment(this); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    // For scenarios where the main activity is launched and user 
    // session is not null, the session state change notification 
    // may not be triggered. Trigger it if it's open/closed. 
    Session session = Session.getActiveSession(); 
    if (session != null && 
      (session.isOpened() || session.isClosed())) { 
     onSessionStateChange(session, session.getState(), null); 
    } 

    uiHelper.onResume(); 
} 

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

@Override 
public void onPause() { 
    super.onPause(); 
    uiHelper.onPause(); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    uiHelper.onDestroy(); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    uiHelper.onSaveInstanceState(outState); 
} 

結果

通常你需要重寫你的活動onActivityResult但調用setFragment()在Facebook登錄按鈕可以讓您的片段在其自己的onActivityResult中接收結果。

如果你想使用一個不同的按鈕(您自己的按鈕爲例):

  • 隱藏facebookLoginButton佈局

  • 呼叫performClick()上facebookLoginButton的onclick監聽器裏您的實際按鈕

就是這樣。

+0

http://stackoverflow.com/questions/34059269/why-the- Facebook的分享 - 是 - - 不工作,與片段 –

相關問題