[Android] Android+Twitter4JでOAuthするためのソースコード

| トラックバック(1) |

twitter4j_oauth.png

Android で Twitter4J を使用し、Twitter の OAuth 処理を行うクラスを作成しました。

特徴としては、動的に WebView を作成し、コールバックページのフックをソースコードで記述しているため、

リソースファイルや AndroidManifest.xml への独自スキーマのための定義が不要であり、

本クラス(1ファイル)を導入するだけで認証できるようになります

※もちろん AndroidManifest.xml への Activity の追加は必要です^^;

※Android 1.5 以降 + twitter4j-android-2.2.2 で確認済

2011/6/5追記:環境によってはshouldOverrideUrlLoading()でフックできない場合があるようです(謎)。
その場合、onPageStarted()で代替できますので、そちらをお使いください。。。

※2012/6/16追記:サンプルコードは http://code.google.com/p/adakoda-android-sample/ に置いてあります。
ライセンスは Apache License 2.0 です。

 

使い方

  • 呼び出し方法

OAuth画面をさせるには、自アプリ用のコールバック文字列、認証用文字列をインテントに設定して呼び出すだけ。

Intent intent = new Intent(this, OAuthActivity.class);
intent.putExtra(OAuthActivity.CALLBACK, CALLBACK);
intent.putExtra(OAuthActivity.CONSUMER_KEY, CONSUMER_KEY);
intent.putExtra(OAuthActivity.CONSUMER_SECRET, CONSUMER_SECRET);
startActivityForResult(intent, REQUEST_OAUTH);

 

  • 結果の取得方法

認証結果は、呼び出し元のonActivityResult()でインテントにセットして返されますので、必要な情報を取得するだけ。

long userId = data.getLongExtra(OAuthActivity.USER_ID, 0);
String screenName = data.getStringExtra(OAuthActivity.SCREEN_NAME);
String token = data.getStringExtra(OAuthActivity.TOKEN);
String tokenSecret = data.getStringExtra(OAuthActivity.TOKEN_SECRET);                

 

OAuth 認証コード(一部)

さて、(何故か)ここでお題。。。

認証処理で必要な処理のうち、getOAuthRequestToken() と getOAuthAccessToken() メソッドは、

呼び出しに時間のかかる処理であり、メイン(UI)スレッドでは呼び出してはいけない処理です。

以下では、AsyncTask で実装しましたが、コードも長くなり、いささか気持ち悪いです。

他にも Thread + Handler などの実装方法が考えられますが、もっとスマートな書き方はないでしょうか?

もっといい書き方あるよ!という方は、Twitter で(ry...

public class OAuthActivity extends Activity {

    // Activity開始時のインテントパラメータ
    public static final String CALLBACK = "callback";
    public static final String CONSUMER_KEY = "consumer_key";
    public static final String CONSUMER_SECRET = "consumer_secret";

    // Activity終了時のインテントパラメータ
    public static final String USER_ID = "user_id";
    public static final String SCREEN_NAME = "screen_name";
    public static final String TOKEN = "token";
    public static final String TOKEN_SECRET = "token_secret";

    private static final String OAUTH_VERIFIER = "oauth_verifier";
    
    private WebView mWebView;
    private String mCallback;
    private Twitter mTwitter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setResult(Activity.RESULT_CANCELED);

        // プログレス表示
        requestWindowFeature(Window.FEATURE_PROGRESS);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

        // Viewのセットアップ
        mWebView = new WebView(this);
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setSavePassword(false);
        mWebView.setWebChromeClient(mWebChromeClient);
        mWebView.setWebViewClient(mWebViewClient);
        setContentView(mWebView);

        // TwitterのOAuth認証画面で毎回ユーザ名、アカウントを入力させるために必要
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.setAcceptCookie(false);

        Intent intent = getIntent();
        mCallback = intent.getStringExtra(CALLBACK);
        String consumerKey = intent.getStringExtra(CONSUMER_KEY);
        String consumerSecret = intent.getStringExtra(CONSUMER_SECRET);
        if ((mCallback == null) || (consumerKey == null)
                || (consumerSecret == null)) {
            finish();
        }

        mTwitter = new TwitterFactory().getInstance();
        mTwitter.setOAuthConsumer(consumerKey, consumerSecret);

        PreTask preTask = new PreTask();
        preTask.execute();
    }

    // 前処理
    public class PreTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            setProgressBarIndeterminateVisibility(true);
        }

        @Override
        protected String doInBackground(Void... params) {
            String authorizationUrl = null;
            try {
                // 非同期処理が必要なメソッドの呼び出し
                RequestToken requestToken = mTwitter.getOAuthRequestToken();
                if (requestToken != null) {
                    authorizationUrl = requestToken.getAuthorizationURL();
                }
            } catch (TwitterException e) {
                e.printStackTrace();
            }
            return authorizationUrl;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            setProgressBarIndeterminateVisibility(false);
            if (result != null) {
                mWebView.loadUrl(result);
            } else {
                finish();
            }
        }

    }

    private WebChromeClient mWebChromeClient = new WebChromeClient() {

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            setProgress(newProgress * 100);
        }

    };

    private WebViewClient mWebViewClient = new WebViewClient() {

        // 特定のページをフック
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            boolean result = true;
            if ((url != null) && (url.startsWith(mCallback))) {
                Uri uri = Uri.parse(url);
                String oAuthVerifier = uri.getQueryParameter(OAUTH_VERIFIER);
                PostTask postTask = new PostTask();
                postTask.execute(oAuthVerifier);
            } else {
                result = super.shouldOverrideUrlLoading(view, url);
            }
            return result;
        }

    };

    // 後処理
    public class PostTask extends AsyncTask<String, Void, AccessToken> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            setProgressBarIndeterminateVisibility(true);
        }

        @Override
        protected AccessToken doInBackground(String... params) {
            AccessToken accessToken = null;
            if (params != null) {
                try {
                    // 非同期処理が必要なメソッドの呼び出し
                    accessToken = mTwitter.getOAuthAccessToken(params[0]);
                } catch (TwitterException e) {
                    e.printStackTrace();
                }
            }
            return accessToken;
        }

        @Override
        protected void onPostExecute(AccessToken result) {
            super.onPostExecute(result);
            setProgressBarIndeterminateVisibility(false);
            if (result != null) {
                long userId = result.getUserId();
                String screenName = result.getScreenName();
                String token = result.getToken();
                String tokenSecret = result.getTokenSecret();
                Intent intent = new Intent();
                intent.putExtra(USER_ID, userId);
                intent.putExtra(SCREEN_NAME, screenName);
                intent.putExtra(TOKEN, token);
                intent.putExtra(TOKEN_SECRET, tokenSecret);
                setResult(Activity.RESULT_OK, intent);
            }
            finish();
        }

    }

}

トラックバック(1)

トラックバックURL: http://mt.adakoda.com/mt-tb.cgi/538

この記事は adakoda 氏の以下の記事のソースコードを導入する際に注意した所、変更した所を記すものです。 元記事:[Android] Android... 続きを読む

2016年8月

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31