Почему интерфейс Android Facebook не работает с фрагментами?

Я переключаю AndroidFacebook код изActivity кFragment, До переключения все работало нормально, но теперьonComplete() обратный вызов не выполняется.

Код Facebook не работает сFragmentsили я что-то не так делаю?

Вот оригинальный код (в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
    }
}

И Activity, и Fragment включают в себя тот же onActivityResult (), как того требует Facebook:

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

Спасибо за вашу помощь!

РЕДАКТИРОВАТЬ: аналогичный вопрос задаетсяВотгде принятым ответом является изменениеFragment кFragmentActivity, Но я не вижу, как это помогает, поскольку тогда это уже неFragment (что мне нужно по другим причинам). Предложения?

РЕДАКТИРОВАТЬ 2: я свернул свое собственное решение. Увидеть ниже.

Ответы на вопрос(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);
    }
}

На самом деле, если вы посмотрите наДокументы Facebook для Android Вы увидите, что в примере входа в систему используется фрагмент.

Существует виджет LoginButton, который предоставляет Facebook SDK, и у него есть метод, называемыйsetFragment и вы передаете целевой фрагмент, с которым вы хотите использовать функциональность входа в систему.

In your fra,gment layout

Добавьте кнопку входа, которую предоставляет 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" />

In your fragment

Создайте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);
}

Result

Обычно вам нужно переопределитьonActivityResult в вашей деятельности, но звонитsetFragment() на Facebook кнопка входа позволяет вашему фрагменту получать результат самостоятельноonActivityResult.

Если вы хотите использовать другую кнопку (например, свою кнопку):

  • hide the facebookLoginButton in layout

  • call performClick() on facebookLoginButton inside the onclick listener of your actual button

Вот и все.

Нам не нужно настраивать 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);
    }  
Решение Вопроса

Насколько я мог определить, API аутентификации Facebook не поддерживаетFragments, В частности,onComplete() обратный звонок из Facebookauthorize() звонок работает сActivities, но не сFragments.

Поэтому я собрал простой обходной путь дляFragments, Решение зависит от того, чтоonActivityResult() также вызывается в родительскомActivity когдаauthorize() вызов завершен, так что вы можете использовать его для установки отдельногоcallback механизм дляFragment.

Сначала установите переменную в родительскомActivity нести цельFragment's имя, скажи

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 ...
}

Я надеюсь, что это может помочь кому-то еще. Ура!

Facebook SDK не работает с Fragment, но работает с FragmentActivity. Итак, вам нужно:

  1. Catch the FB login info in onActivityResult() in your parent FragmentActivity.
  2. Pass activity results to your child Fragment

пример:

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);
        }

Ваш ответ на вопрос