web-dev-qa-db-ja.com

Android-Facebook SDK 3-LoginButtonなしでプログラムでログインする方法

一部の(文字列)コンテンツをウォールポストとして共有するために、Facebook SDKと統合するアプリを作成しています。今、私はHelloFacebookSampleを作成しました。ただし、LoginButtonを使用してユーザーをログインさせます。

それは欲しくない。アクションバーの共有ボタンをクリックしてFacebookで共有するだけです。したがって、プログラムでログインしたいので、LoginButtonの動作をエミュレートしようとしましたが、今のところ成功していません。私は得る

12-06 15:34:33.180:E/AndroidRuntime(19493):Java.lang.UnsupportedOperationException:セッション:保留中のリクエストがあるセッションを再承認しようとしました。

パブリッククラスMainActivityはFacebookActivity {

@SuppressWarnings("serial")
private static final List<String> PERMISSIONS = new ArrayList<String>() {
    {
        add("publish_actions");
    }
};
private final int REAUTHORIZE_ACTIVITY = 3;
private Button postStatusUpdateButton;
private PendingAction pendingAction = PendingAction.NONE;

private enum PendingAction {
    NONE, POST_PHOTO, POST_STATUS_UPDATE
}

/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    postStatusUpdateButton = (Button) findViewById(R.id.postStatusUpdateButton);
    postStatusUpdateButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {
            Log.d("MainActivity", "onClick");
            onClickPostStatusUpdate();
        }

    });

}

@Override
protected void onSessionStateChange(SessionState state, Exception exception) {
    super.onSessionStateChange(state, exception);
}

private interface GraphObjectWithId extends GraphObject {
    String getId();
}

private void showPublishResult(String message, GraphObject result, FacebookRequestError error) {
    String title = null;
    String alertMessage = null;
    if (error == null) {
        title = getString(R.string.success);
        String id = result.cast(GraphObjectWithId.class).getId();
        alertMessage = getString(R.string.successfully_posted_post, message, id);
    } else {
        title = getString(R.string.error);
        alertMessage = error.getErrorMessage();
    }

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title).setMessage(alertMessage).setPositiveButton(getString(R.string.ok), null);
    builder.show();
}

private void onClickPostStatusUpdate() {
    Log.d("MainActivity", "onClickPostStatusUpdate");
    performPublish(PendingAction.POST_STATUS_UPDATE);
}

private boolean hasPublishPermission() {
    Session session = Session.getActiveSession();
    return session != null && session.getPermissions().contains("publish_actions");
}

private void performPublish(PendingAction action) {
    Log.d("MainActivity", "peformPublish");

    Session session = Session.getActiveSession();

    if (session == null) {
        session = new Session.Builder(this).setApplicationId("xxx").build();
        Session.setActiveSession(session);
    }

    if (!session.isOpened()) {
        Session.OpenRequest openRequest = new Session.OpenRequest(this);
        openRequest.setPermissions(PERMISSIONS);
        openRequest.setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
        session.openForPublish(openRequest);
    }

    if (session != null) {
        // postStatusUpdate();
        pendingAction = action;
        if (hasPublishPermission()) {
            // We can do the action right away.
            handlePendingAction();
            // postStatusUpdate();
        } else {
            // We need to reauthorize, then complete the action when we get
            // called back.
            Session.ReauthorizeRequest reauthRequest = new Session.ReauthorizeRequest(this, PERMISSIONS)
                    .setRequestCode(REAUTHORIZE_ACTIVITY).setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
            session.reauthorizeForPublish(reauthRequest);
        }
    }
}

@SuppressWarnings("incomplete-switch")
private void handlePendingAction() {
    PendingAction previouslyPendingAction = pendingAction;
    // These actions may re-set pendingAction if they are still pending, but
    // we assume they
    // will succeed.
    pendingAction = PendingAction.NONE;

    switch (previouslyPendingAction) {
    case POST_STATUS_UPDATE:
        postStatusUpdate();
        break;
    }
}

private void postStatusUpdate() {
    // if (user != null && hasPublishPermission()) {
    if (hasPublishPermission()) {
        // final String message = getString(R.string.status_update,
        // user.getFirstName(), (new Date().toString()));
        final String message = "kks uz nemam nervy";
        Request request = Request.newStatusUpdateRequest(Session.getActiveSession(), message,
                new Request.Callback() {
                    @Override
                    public void onCompleted(Response response) {
                        showPublishResult(message, response.getGraphObject(), response.getError());
                    }
                });
        Request.executeBatchAsync(request);
    } else {
        pendingAction = PendingAction.POST_STATUS_UPDATE;
    }
}

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

}

まあ、これはまだ正しい方法で曲がろうとしているHelloFacebookSampleプロジェクトです。私が試した唯一のことは、セッションの作成に関するものであるperformPublishメソッドです。

より簡単な方法があることを願っています! PS:Facebook SDK 3を使用しています

39
urSus

アクティビティ全体を投稿したのですか?

また、onActivityResultをオーバーライドして、値をSession.getActiveSession()。onActivityResult(...)に渡す必要があります。そうでない場合、セッションはユーザーがアプリを承認したことを認識せず、そのためエラーが表示されます(セッションはまだ保留中の認証リクエストがあると見なしているため、公開を再承認できません)。

21
Ming Li

@Mep Liの回答に@Beppiのコメントを賛成した多くの人と同じ気持ちがあり、アプリでFacebook SDKを使用しているため、最新のFacebook SDK 3.0.bに基づいて、より簡略化されたAPIレベルを作成することにしました。

オープンソースライブラリ:Android-simple-facebook
https://github.com/sromku/Android-simple-facebook

あなたの質問へ:_How to login programatically?_

  1. ログイン/ログアウトリスナーを設定する

    _// set login / logout listener
    OnLoginOutListener onLoginOutListener = new SimpleFacebook.OnLoginOutListener()
    {
    
        @Override
        public void onFail()
        {
            Log.w(TAG, "Failed to login");
        }
    
        @Override
        public void onException(Throwable throwable)
        {
            Log.e(TAG, "Bad thing happened", throwable);
        }
    
        @Override
        public void onThinking()
        {
            // show progress bar or something to the user while login is happening
            Log.i(TAG, "In progress");
        }
    
        @Override
        public void onLogout()
        {
            // change the state of the button or do whatever you want
            Log.i(TAG, "Logged out");
        }
    
        @Override
        public void onLogin()
        {
            // change the state of the button or do whatever you want
            Log.i(TAG, "Logged in");
        }
    };
    
    // set the listener
    mSimpleFacebook.setLogInOutListener(onLoginOutListener);
    _
  2. 任意のビューをクリックすると、login(Activity)メソッドを呼び出すだけです

    _mSimpleFacebook.login(MainActivity.this);
    _


  3. ログアウトするには、logout()メソッドを呼び出します。このような:

    _mSimpleFacebook.logout();
    _

ログイン前に権限を設定する方法、非常にわかりやすい説明を参照 こちら

それが誰かに役立つことを願っています:)

18
sromku

すばらしいコード、ありがとう。

V3 SDKバージョンでは、再認証コードを次のものに置き換える必要があることに注意してください:

Session.NewPermissionsRequest reauthRequest = new Session.NewPermissionsRequest(FacebookActivity.this, PERMISSIONS)
                                .setRequestCode(REAUTHORIZE_ACTIVITY)
                                .setLoginBehavior(SessionLoginBehavior.SSO_WITH_FALLBACK);
                        session.requestNewPublishPermissions(reauthRequest);
1
Benjamin Piette