Twitter4JにてOAuthするプログラム(PINコード,Android4.2以上対応版)

こんにちはABS104aです.

今回はTwitter4Jを用いてAndroidでOAuthを行うプログラムを書いてみたので紹介しようと思います.

 

OAuthはTwitterAPIを使うには必ず必要となった認証です.以前はBASIC認証も使えたのですが,今ではセキュリティ上の理由からアプリケーションにパスワードを渡さなくて済むこの方法が主流になっています.

 

環境はEclipse4.2 ADTで,開発OSはWindows8 64bitです.

とりあえずAndroid用のプログラムを作成して,ビルドパスの構成から,Twitter4Jを読み込んでおきます.

 

このアプリケーションはインターネット通信を必要とするため,まずAndroidManifest.xmlを編集して,

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

を追加しておきます.通信を行う旨の許可が必要ということですね.

 

また,メインのレイアウトファイルはこのように

    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".OAuthActivity" >
 
    <Button
        android:id="@+id/button_showURL"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:text="ShowWebPage" />
 
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/editText"
        android:layout_alignRight="@+id/button_showURL"
        android:text="Oauth" />
 
    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button_showURL"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="26dp"
        android:ems="10"
        android:inputType="number" >
 
        <requestFocus />
    </EditText>
 
</RelativeLayout>

ウェブサイト表示用のボタン,PINコード入力用のEditText,PINコード読み込んでトークンを取得するようのボタンを設置します.

 

そして,MainActivityです.

Android4.2以上からは,HTTP通信を行う際にメインスレッド上(UIスレッド)で処理を行おうとすると例外を吐くようになりました.

ですので,それらの処理を全てAsyncTaskでバックグラウンドに回してしまいます.

 

/**
 * PINコードでTwitterの認証を行うActivity
 * @author ABS104a
 *
 */
public class OAuthActivity extends Activity {

    //アクセストークン
	private static final String TOKEN = "ここにConsumerKeyを入力";
	//トークンシークレット
	private static final String TOKEN_SECRET = "ここにConsumerSecretを入力";
	//Twitter
	private Twitter mTwitter = null;

	//リクエストトークン
	private RequestToken mRequestToken = null;

	private final Activity mActivity = this;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_oauth);

		//ブラウザを開くIntentを飛ばすボタンにリスナをセットする.
		*1
			.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View v) {
					new OnOShowURLButtonClickTask().execute();
				}

			});

		//pin入力後トークンを取得するボタンにリスナをセットする.
		*2
			.setOnClickListener(new OnClickListener(){

				@Override
				public void onClick(View v) {
					new OnOAuthButtonClickTask().execute();
				}

			});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.oauth, menu);
		return true;
	}

	/**
	 * ボタンをタップすると,OAuthの認証URLを取得してブラウザを起動する.
	 * リスナ
	 * @author ABS104a
	 *
	 */
	public class OnOShowURLButtonClickTask extends AsyncTask<Void,Void,Void>{

		@Override
		protected Void doInBackground(Void... params) {
			//Twitterインスタンスを取得
			mTwitter = TwitterFactory.getSingleton();
			//ConsumerKeyをセットする.
			mTwitter.setOAuthConsumer(TOKEN, TOKEN_SECRET);

			try {
				//リクエストトークンを取得
				mRequestToken = mTwitter.getOAuthRequestToken();
				//認証URLを取得
				final String url = mRequestToken.getAuthorizationURL();

				//ブラウザを起動するためのintentを作成.
				final Intent intent = new Intent(Intent.ACTION_VIEW,
	                     Uri.parse(url));
				//intentを起動
				startActivity(intent);
			} catch (TwitterException e) {
				e.printStackTrace();
			}	
			return null;
		}	
	}

	/**
	 * OAuthボタンをタップした時に呼ばれるリスナ
	 * EditTextからPINを読み取りトークンを取得する.
	 * @author ABS104a
	 *
	 */
	public class OnOAuthButtonClickTask extends AsyncTask<Void,Void,AccessToken>{

		@Override
		protected AccessToken doInBackground(Void... params) {
			EditText mEditText = (EditText)mActivity.findViewById(R.id.editText);
			try {
				//アクセストークンを取得
				return mTwitter.getOAuthAccessToken(mRequestToken,mEditText.getText().toString());
			} catch (TwitterException e) {
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(AccessToken result) {
			super.onPostExecute(result);
			if(result == null) return;
			//トークンの書き出し(取得に成功した場合)
			Toast.makeText(mActivity, "Success!", Toast.LENGTH_SHORT).show();
			Toast.makeText(mActivity, result.getToken(), Toast.LENGTH_SHORT).show();
			Toast.makeText(mActivity, result.getTokenSecret(), Toast.LENGTH_SHORT).show();
			//Twitterクラスにアクセストークンをセット(これでTwitterクラスが使えるようになる)
			mTwitter.setOAuthAccessToken(result);

			//Tweetの送信(通常は通信を伴うため別スレッド上で動かす
			//Android4.2以降ではメインスレッドでHTTP投げようとすると例外吐くようです.
			//
			//mTwitter.updateStatus("hogehoge");

		}	

	}

}

このようなプログラムになりました.各機能の説明は他HPで豊富に乗ってるため簡略的に,

例外処理など一部省いている事をご了承ください.

このプログラムで,最後のToast部分でトークンを取得出来ていることが確認できます.

使い方としては,このActivityを認証専用として使って,intentを使って最後のAccessTokenとAccessSecretを元のActivityに返す事で他の作業ができるのではないかと思います.

 

とりあえず今回はPIN方式でやってます.Twitter使ってる方なら一度は目にしたことあると思いますが,認証ボタンを押すと7桁ぐらいの数字を入力してくださいというやつですね.

 

とりあえず,コード全体は

https://github.com/ABS104a/TwitterOAuthTest

に置いておきます.

 

また,質問orつっこみはTwitterの方まで(@ABS104a)お願いします.

 

それでは!

 

 

 

*1:Button)mActivity.findViewById(R.id.button_showURL

*2:Button)mActivity.findViewById(R.id.button