android開発でfacebookと連携する機会は多いと思います。
しかし、androidアプリとfacebook SDKを使ったfacebook連携の日本語の情報は少なめです。そのうえ、facebook SDKのバージョンが古い情報ばかりがネット上だと引っかかるので以下にメモを残します。
環境
- android4.0.2(sdk14)以上
- facebook-android-sdk-3.15
facebook-android-sdk-3.15からはUiLifecycleHelperというactivityやfragmentのライフサイクルを管理するHelperが用意されていますが、今回は使用しません。
理由はあまり必要性を感じなかったことと、様々なactivity, fragment, dialogで実装するのには邪魔だったからです。というわけで、以下、ソースコードです。
FaceBookLogic.java
/**
* facebook共通処理
*/
public class FaceBookLogic {
public static final String TAG = "FaceBookLogic";
/**
* ログイン
*/
public static final int LOGIN = 0;
// アクティビティ
private Activity mActivity;
// 処理の種類
private int type;
// テキスト
private String text;
// 画像
private String imagePath;
// 画像uri
private Uri uri;
/**
*
* @param activity Activity
* @param type 実行種別
*/
public FaceBookLogic(Activity activity, int type, String text, String imagePath, Uri uri) {
super(activity.getApplicationContext());
mActivity = activity;
this.type = type;
this.text = text;
this.imagePath = imagePath;
this.uri = uri;
}
/**
* Facebook認証に接続する
* @see http://woodsmall.co.jp/android/android%E3%82%A2%E3%83%97%E3%83%AA%E3%81%ABfacebook-sdk%E3%82%92%E5%B0%8E%E5%85%A5/
*/
public void connectFacebookAuth() {
outputLog();
Settings.addLoggingBehavior(LoggingBehavior.INCLUDE_ACCESS_TOKENS);
// セッションを生成
Session session = Session.getActiveSession();
setSession(session);
}
/**
* セッションを設定する
*/
private void setSession(Session session) {
if (session == null) {
if (session == null) {
session = new Session(mContext);
}
// アクティブセッションとする。
Session.setActiveSession(session);
if (session.getState().equals(SessionState.CREATED_TOKEN_LOADED)) {
// 認証を要求する。
session.openForRead(new Session.OpenRequest(mActivity).setCallback(statusCallback));
}
}
// ログイン状態の確認
if (!session.isOpened()) {
Log.d(TAG, "no login");
facebookLogin();
}
}
/**
* facebookにログインする
* @see https://groups.google.com/forum/#!topic/android-group-japan/wrxo9q-ydl0
*/
private void facebookLogin() {
// セッションを生成
Session session = Session.getActiveSession();
Log.d(TAG,"doLogin: session state is " + session.getState() + ", isOpend:" + session.isOpened() + ", isClosed:" + session.isClosed());
if (!session.isOpened()) {
if (session.isClosed()) {
session = new Session(mContext);
Session.setActiveSession(session);
}
session.openForRead(new OpenRequest(mActivity).setCallback(statusCallback));
} else {
Log.d(TAG, "activeSession");
Session.openActiveSession(mActivity, true, statusCallback);
}
}
private Session.StatusCallback statusCallback = new SessionStatusCallback();
private class SessionStatusCallback implements Session.StatusCallback {
@Override
public void call(Session session, SessionState state, Exception exception) {
Log.d(TAG, "SessionStatusCallback");
onSessionStateChange(session, state, exception);
}
}
/**
* セッションが開いた時にcallbackする
* @param session
* @param state
* @param exception
*/
private void onSessionStateChange(Session session, SessionState state, Exception exception) {
// final Session tempSession = session;
Log.d(TAG, "state:" + state.isOpened());
Log.d(TAG, "session:" + session.isOpened());
Log.d(TAG, "accessToken:" + session.getAccessToken());
if (session.isOpened()) {
Log.d(TAG, "Logged in...");
// ログイン
if (LOGIN == type) {
// something
}
} else if (state.isClosed()) {
Log.i(TAG, "Logged out...");
}
}
/**
* ログを出力
*/
private void outputLog() {
Log.d(TAG, "action acitivty is " + mActivity);
}
}
呼び出し側
MainActivity.java
FaceBookLogic logic = new FaceBookLogic(getApplicationContext());
logic.connectFacebookAuth();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult :" + requestCode);
Log.d(TAG, "onActivityResult resultCode:" + resultCode);
// Session.getActiveSession().onActivityResult(this, requestCode, resultCode, data);
Log.d(TAG, "onActivityResult call:");
switch (requestCode) {
case REQUEST_FACEBOOK_ACCOUNT:
if (resultCode == RESULT_OK) {
Log.d(TAG, "facebook seceess:");
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession()
.onActivityResult(this, requestCode, resultCode, data);
} else {
Log.d(TAG, "facebook cancel");
super.onActivityResult(requestCode, resultCode, data);
Session.getActiveSession().closeAndClearTokenInformation();
}
break;
}
}
twitterなどのログインに比べると複雑です。理解するべきことはsessionの値の変化とsession取得時のcalbackの動きです。
一度立ち上げたfacebookアプリがユーザーに閉じられた場合は、セッションを切断する必要があります。*session.getActiveSession().closeAndClearTokenInformation()
でないとsessionが残ってしまい、連続でfacebookアプリを立ち上げることができなくなってしまいます。
onSessionStateChangeは、セッションの状態が変化すると呼び出されます。このメソッドの中でtokenを取得して、各アプリに必要なロジックを記述していくことになります。