5

次のコードを使用して、Facebook ログインをポップアップする画面があります。

    //facebook stuff
    if (Session.getActiveSession() == null ||  Session.getActiveSession().isClosed()) {
        Session.openActiveSession(this, true, null);
    }

ユーザーが「戻る」ボタンを押してログインを閉じると、Facebook で保護されているはずの画面に自動的に送信されます (ユーザーがログインしていないためエラーが発生します)。

これをどのように処理すればよいですか?古いSDKか何かで、それがあったことがわかります:

facebook.isSessionValid()

これを行う方法はまだありますか?もしそうなら、私は実際にどのようにそれをしますか? 彼らが最終的に取り消そうとするのをやめるまで、ある種のwhileループですか?その画面からのバックアウトを無効にする方法はありますか? 私はその画面をまったく生成しません。Facebook は生成します。これは私が一緒に暮らさなければならない単なるバグですか?

編集:

これの当然の結果として、Facebook アプリを使用してログアウトすると、Facebook SDK は自分のアプリでこれを通知しないことに気付きました。それでも認証されます。さらに悪いのは、ログアウトした後でも、Facebook アプリを使用してまったく別のユーザーとしてログインした場合です。どうすればこれを処理できますか?

編集:その他のコード

これは、Facebook にログインし (アクティビティの onCreate で)、グラフ ユーザーと友達を取得するように依頼する方法です (最初に私を取得し、非同期処理が完了したら、友達を取得します)。

if (Session.getActiveSession() == null ||  Session.getActiveSession().isClosed()) {
            Log.v(CLASS_NAME, "Logging into facebook");
            //Session.openActiveSession(this, true, new Session.statusCallback());
            final Session.StatusCallback sessionStatusCallback = new Session.StatusCallback() {

            @Override
            public void call(Session session, SessionState state,
                    Exception exception) {
                // TODO Auto-generated method stub
                    if(exception != null)
                    {
                        // Handle fail case here.
                        Log.v(CLASS_NAME, "Facebook login error " + exception);
                        return;
                    }

                    // If session is just opened...
                    if(state == SessionState.OPENED)
                    {
                        // Handle success case here.
                        Log.v(CLASS_NAME, "Facebook login success!");
                        return;
                    }


            }

        };

        Session.openActiveSession(this, true, sessionStatusCallback);
    }


    //annonymous inner class
    final Callback<ArrayList<GraphUser>> inner_callback_class2 = new FacebookHelper.Callback<ArrayList<GraphUser>>() {
        @Override
        public void setResult(ArrayList<GraphUser> result) throws Exception {
            // TODO Auto-generated method stub
            for(GraphUser user : result){
                friends.put(user.getId(), user);
            }
            friends.put(me.getId(), me); //i can see my own comments as well


            //get comments
            //ArrayList<String>tmp = new ArrayList<String>();
            //tmp.add("Jenny");
            //tmp.add("Charles");
            //initial comment call so I can view them
            //
            getComments();
        }
    };


    //annonymous inner class
    FacebookHelper.Callback<GraphUser> inner_callback_class = new FacebookHelper.Callback<GraphUser>() {
        @Override
        public void setResult(GraphUser result) throws Exception {
            // TODO Auto-generated method stub
            me = result;
            Log.v("ANYTHING", me.getName());
            //make sure i have an id before I do anything
            FacebookHelper.getMyFriends(Session.getActiveSession(),inner_callback_class2);
            //post comment
            //RailsServerHelper.postComment("Comment Testing", movie.id, myID, currentNPT);
        }
    };

    FacebookHelper.getMyID(Session.getActiveSession(), inner_callback_class);

これは、(静的ヘルパークラスで)友達を取得する方法です。

public static void getMyFriends(final Session session, final Callback<ArrayList<GraphUser>> callback){
    Request request = Request.newMyFriendsRequest(session, new Request.GraphUserListCallback() {
        @Override
        public void onCompleted(List<GraphUser> users, Response response) {
            // TODO Auto-generated method stub
            ArrayList<GraphUser> tmp = new ArrayList<GraphUser>(users);
            try {
                callback.setResult(tmp);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });
    request.executeAsync(); 

}

私が持っている唯一の他のFacebookのことは、あなたが提案したセッションのことを完全にクリアすることです:

@Override
public void onDestroy(){
    Session.getActiveSession().closeAndClearTokenInformation();
    Log.v(CLASS_NAME, "Clearing facebook session");
    pleaseStop = true;
    super.onDestroy();
}

まったくログインできなくなります。私はそれをテストしている2つのデバイスを持っています。

最初のデバイスはもともと 1 つのプロファイルで正常に動作していましたが、2 番目のプロファイルを試してみると、最初のプロファイルがログアウトされなかったので、closeAndClearTokenInformation() を実行しました。その結果、プロファイルがなくなり、Facebookのログイン全体がポップアップしなくなりました。「Facebookにログインしています」と常に出力され、getMe呼び出しが機能しないため、プロファイルがないと思います。(ただし、ここで私のコードを説明するだけで、getMe のものを Facebook のログイン コールバックに入れることができることがわかります) また、callBack に入れた成功ステートメントを出力することはありません。戻るボタンを押します (その画面にどれだけ座っていても)。

ログイン画面で戻るボタンが押されたため、2 番目のデバイスはプロファイルをログインできませんでした。それ以来、システムは「ログイン」している人がいないと見なしているようで、何をしてもシステムを更新できません。最初のデバイスのようにログインしようとしているのを見たことがありません。closeAndClear 呼び出しは、このデバイスでは何もしていないようです。関連する場合、2 番目のデバイスは、まったく別のマシンで実行される仮想シミュレーターです。

実際のデバイスでは、次のように表示されます。

01-24 07:16:04.669: V/MakeAndViewCommentsActivity(3677): Logging into facebook

そして、一連のシステム メッセージ (私は 10 分以上待ちました) が表示されますが、警告やエラーはないようです。

01-24 07:29:05.548: V/MakeAndViewCommentsActivity(3677): Clearing facebook session
01-24 07:29:05.552: V/MakeAndViewCommentsActivity(3677): Facebook login error com.facebook.FacebookException: Log in attempt aborted.

FacebookのopenActiveSessionが返されないのはなぜですか?

編集: Facebook のサンプル アプリでは元のログインが引き続き機能しますが、実際の Facebook アプリでログアウトしたりユーザーを変更したりしても問題ありません。セッションのクリアも含まれていないと思いますか?

編集:次の印刷ステートメントがある場合:

Log.v(CLASS_NAME, "Facebook callback with state: " + state);

そうですか:

01-24 09:10:54.333: V/MakeAndViewCommentsActivity(4869): Facebook callback with state: OPENING

コールバックは一度だけ呼び出されますか? それとも理論上、完了すると「OPEN」の状態で再度呼び出されるのでしょうか?

解決:

編集:「OPENING」状態を決して離れないという事実を調べると、コードを追加する必要があったことがわかりました。

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

そして、それはうまくいきました!理由がわかりません。これについては調査を行うことになると思いますが、ようやくユーザーを変更できてうれしいです。

4

1 に答える 1

0

null コールバックを渡しています。コールバックを実装すると、コールバックが呼び出されることがわかります。state.isClosed() をチェックすると、true が返されます (状態は CLOSED_LOGIN_FAILED になるはずです)。また、例外パラメーターにも例外が必要です。ユーザーが SSO からバックアウトする機能を無効にすることはできません。これは仕様です。

ユーザーが Facebook アプリからログアウトした場合、通知がないという点でも正しいです。ユーザー エクスペリエンスを向上させる方法の 1 つは、ユーザーの代わりに何かをしている場合 (ステータスの投稿など)、常にユーザーの名前とプロフィール画像を表示することです。これにより、正しいユーザーではないことがすぐにわかります。他のオプションは、アプリが終了するたびに常に session.closeAndClearTokenInformation を呼び出すことです。このようにして、常に新しいセッションを開始し、ユーザーが facebook アプリをインストールしている場合でも、認証は非常に高速です (追加のボタンを押す必要はありません)。欠点は、Facebook アプリを持っていない場合、毎回ログイン用の Web ダイアログがポップアップすることです (ただし、FB アプリの存在を確認することでおそらく回避できます)。

于 2013-01-22T19:04:24.917 に答える