▼Androidメモ▼
OAuthによるTwitter通信


OAuthによるTwitter通信を行うプログラムを作成する。


アプリの登録
Twitterの連携アプリの登録ページでアプリの登録を行う。
アプリケーションの種類は「ブラウザアプリ」、コールバックURLには適当なURLを記述。
インテントでWebブラウザを開いて認証を行い、証明書となるトークンを元のアクティビティに戻してもらうため。
consumerKeyとconsumerSecretを取得し、ソースコードに記述。

ライブラリの追加
オープンソースライブラリ「oauth-signpost」を使用する。 「signpost-core-1.2.1.1.jar」と「signpost-commonshttp4-1.2.1.1.jar」をダウンロードしてパスを通す。ライブラリの追加方法は「Package Explorerのプロジェクト名を右クリック→Properties→Java Build Path→Libraries」でAdd JARsボタン。

ソースコード
OAuthTwitterEx.java
package net.npaka.oauthtwitterex;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.view.Window;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.protocol.HTTP;
import org.xmlpull.v1.XmlPullParser;

//OAuthによるTwitter通信
public class OAuthTwitterEx extends Activity {
    private final static String 
        consumerKey   ="自分のconsumerKeyを記述",
        consumerSecret="自分のconsumerSecretを記述";
    private final String CALLBACKURL="myapp://mainactivity";

    private TextView                 textView;
    private CommonsHttpOAuthConsumer consumer;
    private OAuthProvider            provider;
    
    //初期化
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        //レイアウトの生成
        LinearLayout layout=new LinearLayout(this);
        layout.setBackgroundColor(Color.rgb(255,255,255));
        layout.setOrientation(LinearLayout.VERTICAL);
        setContentView(layout); 

        //テキストビューの生成
        textView=new TextView(this);
        textView.setTextSize(16.0f);
        textView.setTextColor(Color.rgb(0,0,0));
        setLLParams(textView);
        layout.addView(textView);
        
        //認証
        doOauth();
    }
    
    //認証
    private void doOauth() {
        try {
            consumer=new CommonsHttpOAuthConsumer(consumerKey,consumerSecret);
            provider = new DefaultOAuthProvider(
                "http://twitter.com/oauth/request_token",
                "http://twitter.com/oauth/access_token",
                "http://twitter.com/oauth/authorize");
            
            //トークンの読み込み
            SharedPreferences pref=getSharedPreferences(
                "token",MODE_PRIVATE);
            String token      =pref.getString("token","");
            String tokenSecret=pref.getString("tokenSecret","");
            
            //認証済み
            if (token.length()>0 && tokenSecret.length()>0) {
                consumer.setTokenWithSecret(token,tokenSecret);
                
                //Twitter操作
                getTimeline();
                updateStatus("Date>"+(new Date()).toString());
            } 
            //認証処理のためブラウザ起動
            else {
                String authUrl=provider.retrieveRequestToken(consumer,CALLBACKURL);
                this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));
            }
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(),Toast.LENGTH_LONG).show();
        }
    }
    
    //認証完了時に呼ばれる
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Uri uri=intent.getData();
        if (uri!=null && uri.toString().startsWith(CALLBACKURL)) {
            String verifier=uri.getQueryParameter(
                oauth.signpost.OAuth.OAUTH_VERIFIER);
            try {
                provider.retrieveAccessToken(consumer,verifier);

                //トークンの書き込み
                SharedPreferences pref=getSharedPreferences(
                    "token",MODE_PRIVATE);
                SharedPreferences.Editor editor=pref.edit();
                editor.putString("token",consumer.getToken());
                editor.putString("tokenSecret",consumer.getTokenSecret());
                editor.commit();

                //Twitter操作
                getTimeline();
                updateStatus("Date>"+(new Date()).toString());
            } catch(Exception e){
                Log.d("",e.getMessage());
            }
        }
    }

    //タイムラインの取得
    private void getTimeline() {
        try {
            //接続
            HttpGet httpGet=new HttpGet(
                "http://twitter.com/statuses/friends_timeline.xml"); 
            consumer.sign(httpGet);
            DefaultHttpClient http=new DefaultHttpClient();
            HttpResponse execute=http.execute(httpGet);
            
            //XMLのパース処理
            InputStream in=execute.getEntity().getContent();
            final XmlPullParser parser=Xml.newPullParser();
            parser.setInput(new InputStreamReader(in));
            String tagName=null;
            while (true) {
                int type=parser.next();
                //タグ開始
                if (type==XmlPullParser.START_TAG) {
                    tagName=parser.getName();
                } 
                //テキスト
                else if (type==XmlPullParser.TEXT) {
                    if (parser.getText().trim().length()==0) {
                    } else if (tagName.equals("screen_name")) {
                        textView.append("("+parser.getText()+")\n");
                    } else if (tagName.equals("text")) {
                        textView.append(parser.getText());
                    }
                }
                //ドキュメント終了
                else if (type==XmlPullParser.END_DOCUMENT) {
                    break;
                }                
            }

            //切断
            in.close();
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(),Toast.LENGTH_LONG).show();
        }
    }

    //つぶやき送信
    private void updateStatus(String status) {
        try {
            HttpPost post=new HttpPost("http://twitter.com/statuses/update.xml"); 
            final List<NameValuePair> params=new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("status",status));  
            post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));  
            post.getParams().setBooleanParameter(
                CoreProtocolPNames.USE_EXPECT_CONTINUE,false);
            consumer.sign(post);
            DefaultHttpClient http=new DefaultHttpClient();
            http.execute(post);
        } catch (Exception e) {
            Toast.makeText(this, e.getMessage(),Toast.LENGTH_LONG).show();
        }
    }
    
    //ライナーレイアウトのパラメータ指定
    private static void setLLParams(View view) {
        view.setLayoutParams(new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT));
    }
}


AndroidManifest
 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="net.npaka.oauthtwitterex"
    android:versionCode="1"
    android:versionName="1.0">

    <application 
        android:icon="@drawable/icon" 
        android:label="@string/app_name">
        
        <activity 
            android:name=".OAuthTwitterEx"
            android:label="@string/app_name" 
            android:launchMode="singleInstance">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <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="myapp" android:host="mainactivity" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="4" />

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

</manifest>


−戻る−