2013 年 5 月 7 日

アンドロイドアプリからTwitterへログインする方法

アンドロイドアプリからTwitterへログインする方法

数回にわたり、アンドロイドアプリからソーシャルログインする方法をご紹介してきました。今回はTwitter4jを利用したTwitterへのログイン方法をご紹介します。

バージョンは3.0.3を利用します。3.0.3はTwitter API v1.1に完全対応しているそうです(Twitter API v1は2013/6/11までしか利用できません。当初は2013/5/7でしたが順延されました)。また、アンドロイド版も統合されたもので、スリム化もなされているそうです。

認証はFacebook,Google+とは違ってブラウザを介して行います。ブラウザではなくWebViewを使う例もあるようですが、悪意のあるアプリに偽装される可能性も指摘されています。その他には、PINコード入力で認証する方法もあるようです。

ダウンロード

Twitter4jは以下のサイトからダウンロードします。ダウンロードが完了したら、お好きな場所で解凍してください。このzipファイルはトップディレクトリがありませんので、一旦Twitter4jなどディレクトリを作成して、そこで解凍した方がよいと思います。

Twitter4j

新しいTwitterアプリを作成

TwitterのDevelopersサイトにて、Twitterアプリを作成します。

Twitter Developers

ログインしたら、右上のメニューからMy applicationsを選択します。そして、右上のCreate a new applicationをクリックします。

アプリが作成できたら、Settingsタブで以下の設定を確認します。Callback URLは何か入力しておいてください。ログインのみなら、これだけの設定でいいです。

Application Type:Read only
Callback URL: 適当なURLを入力
Allow this application to be used to Sign in with Twitterをチェック

そして、DetailsタブのConsumer keyとConsume secretを後で利用しますので、控えておいてください。

Consumer key: vTgJBTWByhRL5sBMWVf3Q
Consumer secret: tnusuOTBPDJf6cYOFDzmRWqonIcVbjaouEoI6helCI

Twitterログインアプリを作成

アンドロイドアプリのプロジェクトを作成します。特に注意しないといけない点はありません。

Twitter4jライブラリを追加

先ほどダウンロードしたアーカイブのlibディレクトリのtwitter4j-core-3.0.3.jarをプロジェクトのライブラリに追加します。Package Explorerのlibsディレクトリにドラッグ&ドロップでもいいです。

マニフェストに追記

マニフェストにインターネットのパーミッションを追加します。

<uses-permission android:name="android.permission.INTERNET"/>

MainActivityのインテントフィルターを追加しておきます。これは認証後にこのアクティビティに戻ってくるときに利用されます。callbackスキームで呼び戻されます。

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="callback" android:host="twitterlogin" /> <!-- schemeはユニークなものを任意 -->
</intent-filter>

変数の定義

コンシューマーキーとコンシューマーシークレットはさきほどのTwitterアプリ作成で取得したものを設定します。

  static final String sCONSUMER_KEY    = "vTgJBTWByhRL5sBMWVf3Q";
  static final String sCONSUMER_SECRET = "tnusuOTBPDJf6cYOFDzmRWqonIcVbjaouEoI6helCI";
  static final String sCALLBACK = "callback://twitterlogin";
  static final String sAUTH_VERIFIER = "oauth_verifier";

  private Button mTwloginBtn = null;
  private static RequestToken sRequestToken = null;
  private static OAuthAuthorization sOauth = null;

RequestTokenとOAuthAuthorizationをクラススタティック変数にしているのは、アクティビティのlaunchModeがデフォルトだと、コールバックされたintentに応答するとき、新しいアクティビティが生成されてしまうからです。アクティビティのlaunchModeをsingleTaskにして、onNewIntentで認証処理すれば、インスタンスメンバ変数でもいいです。

onNewIntentでの認証

  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    initTwitter(intent);
  }

初期処理

ボタンを初期化します。

mTwloginBtn = (Button)findViewById(R.id.buttonAuth);   
mTwloginBtn.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View view) {
    loginTwitter();
  }
});

以下の処理をonCreateで呼び出します。ブラウザの認証から戻ってきたときは、アクセストークンを取得します。アクセストークンが取得できれば、ログイン完了とみなします。

// onCreateから、initTwitter(getIntent())を呼び出す。

private void initTwitter(Intent intent) {

  //Twitterの認証画面からコールバックされるIntentからUriを取得する。
  final Uri uri = intent.getData();

  if (uri != null && uri.toString().toLowerCase(Locale.getDefault()).startsWith(sCALLBACK)) {
    // 認証から戻ってきたときのアクティビティの呼び出しである。
    new AsyncTaskWithProgressDialog("wait..") {
      @Override
      protected Void doInBackground(Void... arg0) {
        try {
          // oauth_verifierパラメータからAccessTokenオブジェクトを取得して、ログに出力する。
          // tokenには、screen_nameとuserIdが含まれる。
          String verifier = uri.getQueryParameter(sAUTH_VERIFIER);
          AccessToken token = sOauth.getOAuthAccessToken(sRequestToken, verifier);
          Log.d(TAG, "token = " + token);

        } catch (TwitterException e) {
          Log.e(TAG, e.toString());
        }
        return null;
      }
    }.execute();
  }
}

ログイン

ログインボタンがタップされたら、認証画面をブラウザから呼び出します。

private void loginTwitter() {
  /* 
   * Android 3.0.x以降はUIスレッドでHTTP通信ができない。
   */
  new AsyncTaskWithProgressDialog("wait...") {

    @Override
    protected Void doInBackground(Void... arg0) {

      // Twitter4jの設定情報を読む。
      Configuration conf = ConfigurationContext.getInstance();

      // OAuthオブジェクトを作成する。
      sOauth = new OAuthAuthorization(conf);

      // OAuthオブジェクトにconsumerKeyとconsumerSecretを設定する。
      // プロパティファイルで設定する方法もある。
      sOauth.setOAuthConsumer(sCONSUMER_KEY, sCONSUMER_SECRET);

      try {
        // リクエストトークンを生成する。
        sRequestToken = mOauth.getOAuthRequestToken(sCALLBACK);
      } catch (TwitterException e) {
        Log.e(TAG, e.toString());
      }
      String uri = sRequestToken.getAuthorizationURL();
      startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse(uri)), 0);
      return null;
    }  
  }.execute();
}

非同期処理中のプログレス

HTTP通信中にプログレスを表示するクラスです。

class AsyncTaskWithProgressDialog extends AsyncTask<Void, Void, Void> {

  private String mMessage = null;
  private ProgressDialog mProgress = null;

  public AsyncTaskWithProgressDialog(String message) {
    mMessage = message;
  }

  @Override
  protected void onPreExecute() {
    mProgress = new ProgressDialog(MainActivity.this);
    mProgress.setMessage(mMessage);
    mProgress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    mProgress.show();     
  }

  @Override
  protected void onPostExecute(Void result) {
    mProgress.dismiss();
  }


  @Override
  protected Void doInBackground(Void... params) {
    return null;
  }  
}

実行

起動すると以下のような画面になります。ログインボタンをタップすると認証画面へ遷移します。

アカウントを入力して、連携アプリを認証をタップすると、元の画面へ戻ります。

認証に成功すると以下のようなアクセストークンが取得できます。

token = AccessToken{screenName='notice_inc', userId=*******}

ブラウザを使った認証なので、通常のWebアプリでTwitterログインを経験している人にとっては、比較的わかりやすいと思います。