2

一部のAndroidFacebookコードをからに切り替えActivityていFragmentます。切り替え前はすべて正常に機能していましたが、現在はonComplete()コールバックが実行されていません。

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

アクティビティとフラグメントの両方に、Facebookで必要とされるものと同じonActivityResult()が含まれています。

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

ご協力いただきありがとうございます!

編集:同様の質問がここで尋ねられます。受け入れられた答えは、をに変更するFragmentことFragmentActivityです。しかし、これがどのように役立つかはわかりません。これは、もはやFragment(他の理由で必要です)ではないためです。提案?

編集2:私は自分の解決策を転がしました。下記参照。

4

5 に答える 5

12

私が判断できる限り、Facebook認証APIはフラグメントをサポートしていません。具体的にはonComplete()、Facebookauthorize()呼び出しからのコールバックは、アクティビティでは機能しますが、フラグメントでは機能しません。

そこで、フラグメントの簡単な回避策をまとめました。解決策は、呼び出しが完了したときに親アクティビティ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);
}

これで、新しいmyCallBack()関数のonComplete()コールバックに通常配置するコードを模倣できます。

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

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

これが他の誰かに役立つことを願っています。乾杯!

于 2012-06-09T20:36:29.593 に答える
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);
    }
}
于 2012-11-15T09:15:53.000 に答える
2

Facebook SDKはFragmentでは機能しませんが、FragmentActivityでは機能します。だからあなたは必要です:

  1. 親FragmentActivityのonActivityResult()でFBログイン情報をキャッチします。
  2. アクティビティの結果をお子様のフラグメントに渡します

例:

1.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.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);
        }
于 2013-04-09T13:07:33.530 に答える
2

実際、Android用のFacebook Docsを見ると、ログイン例でフラグメントが使用されていることがわかります。

Facebook SDKが提供するLoginButtonウィジェットがあり、 setFragmentというメソッドがあり、ログイン機能を使用するターゲットフラグメントを渡します。

フラグメントレイアウトで

FacebookSDKが提供するログインボタンを追加します。

        <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をオーバーライドする必要がありますが、FacebookのログインボタンでsetFragment()を呼び出すと、フラグメントが独自のonActivityResultで結果を受け取ることができます。

別のボタン(たとえば、独自のボタン)を使用する場合:

  • レイアウトでfacebookLoginButtonを非表示にします

  • 実際のボタンのonclickリスナー内のfacebookLoginButtonでperformClick()を呼び出します

それでおしまい。

于 2014-12-25T08:42:12.890 に答える
0

フラグメントクラスのメインアクティビティ内およびフラグメント内でonActivityResultを構成する必要はありません。フラグメントを含むメインアクティビティ内に以下のコードを配置し、フラグメント内に残りのfacebooksdkコードを実行するだけです...とても簡単です。

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) 
    {
        super.onActivityResult(requestCode, resultCode, data);
        Session.getActiveSession().onActivityResult(ChatScreen.this, requestCode,
                resultCode, data);
    }  
于 2014-06-30T11:18:41.030 に答える