AndroidでTwitterのOauth認証(Twitter4j使用)

Andoridの入門書をざっくりとですが、一冊ほど目を通して、なんとなーく概要がつかめたので、少しずつえごリブアプリを作ってます。

Androidのシミュレータ重いってレベルじゃねーぞ

で、えごリブはTwitterを使って認証してるのでAndroidでもOauth認証させる必要があったので、どうやるのか調べてみました。

基本的な流れはWebとあまり変わらない。

  1. TwitterFactory#getInstanceでtwitterインスタンスを作成(必要に応じてConsumeKeyとConsumeSecretKeyをセット)
  2. twitter#getOauthRequestTokenでリクエストトークンを作成
  3. requestToken#getAuthorizationURLで認証用URLを取得
  4. 認証画面に飛ばす(ブラウザを起動させる)
  5. 認証に成功したらアプリケーションに戻ってoauth_verifierパラメータを取得
  6. twitter#getOuathAccessTokenでアクセストークンを取得
  7. 取得したアクセストークンをプリファレンスに保存するなり、それを使用してツイートしたりご自由に


Androidのシミュレータ重いってレベルじゃねーぞ

Webと違うのは認証後にブラウザから自分のアプリケーションを起動させるところ。
あとは大体同じ。
Webから自分のアプリケーションを起動させる方法はスキーマを設定してあげると出来る模様。

http://www.atmarkit.co.jp/fsmart/articles/androidmixi/01.html

上記サイトの流れと基本一緒です。(上記はmixiのOauth認証)

具体的なソースとかは下記みたいな感じ。
あ、ちなみにtwitter4jのバージョンは2.2.1です。

まずAndroidManifest.xmlを変更

<activity
      android:name=".common.TwitterOauth"
      android:label="@string/twitter_oatuh_title"
      android:launchMode="singleTask"
      >
      <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="egolib" android:host="callback" />
      </intent-filter>
</activity>

こんな感じ。
activityにlaunchModeを追加。
intentにスキーマを設定してます。
Androidのシミュレータ重いってレベルじゃねーぞ
次にlayoutを作成

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  
  <TextView
    android:id="@+id/tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=""/>
    
  <TextView
    android:id="@+id/token"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=""/>
    
  <TextView
    android:id="@+id/secret_token"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=""/>
</LinearLayout>

このサンプルは単純に認証が終わったらTextViewにAccessTokenの値を表示してるだけ。
Androidのシミュレータ重いってレベルじゃねーぞ
で、Activityを作成

package sample.common;

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;

import sample.android.R;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class TwitterOauth extends Activity {
  private static final String CALLBACK_URI = "egolib://callback";
  private static final String VERIFIER = "oauth_verifier";
  
  private Twitter twitter;
  private RequestToken requestToken;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.twitter_oauth);
    try{
      //consumeKey,consumeSecretKeyはtwitter4j.propertiesに記述
      twitter = new TwitterFactory().getInstance();
      requestToken = twitter.getOAuthRequestToken(CALLBACK_URI);

      String url = requestToken.getAuthorizationURL();
      Intent i = new Intent(Intent.ACTION_VIEW , Uri.parse(url));
      //ブラウザ起動
      startActivity(i);
    }catch(TwitterException e){
      Log.e("oauth_error", e.getMessage());
    }
  }
  
  /**
   * コールバック時
   */
  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    TextView tv = (TextView)findViewById(R.id.tv);
    
    Uri uri = intent.getData();
    if(uri == null || !uri.toString().startsWith(CALLBACK_URI)){
      tv.setText("こんなの絶対おかしいよ。");
      return;
    }
    AccessToken aToken = null;
    String verifier = uri.getQueryParameter(VERIFIER);
    if(verifier == null || verifier.length() == 0){
      tv.setText("認証が拒否されたし。");
      return;
    }
    try{
      aToken = twitter.getOAuthAccessToken(requestToken, verifier);
    }catch(TwitterException e){
      Log.e("oauth_error" , e.getMessage());
      tv.setText("失敗した!");
      return;
    }
    tv.setText("success");
    TextView token = (TextView)findViewById(R.id.token);
    token.setText(aToken.getToken());
    TextView sToken = (TextView)findViewById(R.id.secret_token);
    sToken.setText(aToken.getTokenSecret());
  }
}

Androidのシミュレータ重いってレベルじゃねーぞ

エラー処理は適当です。
このActivityは起動した瞬間にTwitterの認証ページにすっ飛ばしてます。
使い方としては、他のActivityで認証ボタンなんかを用意して、このActivityに飛ばすとかって感じですかね。

おかしなところがあったら教えてくれるとうれしいです。