AndroidでTwitterクライアントアプリを開発する(開発編)

前回(AndroidでTwitterクライアントアプリを開発する(準備編))の続きで今回は実際の開発のところをつらつらと書いていく。

以下作成の手順

  1. 下準備1(twitter4Jのダウンロード)
  2. 下準備2(twitterアプリの登録)
  3. プロジェクト作成
  4. twitter4jのjarファイルをビルド・パスに追加する
  5. AndroidManifest.xmlの編集
  6. layoutの作成
  7. 定義ファイルの作成
  8. Activityの設定

5.AndroidManifest.xmlの編集

今回開発するアプリは、トリガとなるページとTwitterの認証画面を表示するページの2枚のアクティビティが必要なので、それらを追加。インターンネットへの接続も許可しなくてはならないので、uses-permissionにINTERNETも追加。

例)

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

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".IndexActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <data android:scheme="testtwitter" android:host="twitter4j" android:path="/"/>
            </intent-filter>
        </activity>
        <activity android:name=".LoginTwitterActivity" ></activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

6.layoutの作成

ボタンのページ(main.xml)、Twitterの認証画面(login.xml)を表示するページを作成

例)
main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center" >

    <Button
        android:id="@+id/tweet"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="ツイートする" />
</LinearLayout>

login.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <WebView
        android:id="@+id/login"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

7.定義ファイルの作成

consumer keyとかを設定。
例)

public class TwitterConst {

       // Application key
       public static final String CONSUMER_KEY = "/* Twitter developerで取得するconsumer keyの値 */";
       // Application secret code
       public static final String CONSUMER_SECRET = "/* Twitter developerで取得するconsumer secretの値 */";
       // Twitterアプリ承認時にコールバックされるURL
       public static final String CALLBACK_URL = "testtwitter://twitter4j";
       // Twitterアプリ承認時にコールバックされるURLの認証トークンパラメーター情報
       public static final String PARAM_OAUTH_TOKEN = "oauth_token";
       // Twitterアプリ承認時にコールバックされるURLの認証立証パラメーター情報
       public static final String PARAM_OAUTH_VERIFIER = "oauth_verifier";
       // 認証後パラメータ参照キー
       public static final String PREF_KEY = "twitter_setting";
       // 認証後パラメータOAuth token参照キー
       public static final String SUB_KEY_OAUTH_TOKEN = "oauth_token";
       // 認証後パラメータOAuth token secret参照キー
       public static final String SUB_KEY_OAUTH_TOKEN_SECRET = "oauth_token_secret";
}

8.Activityの設定

ボタンのページ(IndexActivity)、Twitterの認証画面(LoginTwitterActivity)を表示するページを作成
例)
IndexActivity.java

public class IndexActivity extends Activity {

       private OAuthAuthorization twitterOauth;
       private RequestToken requestToken;
       private AccessToken accessToken;
       private SharedPreferences pref;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pref = getSharedPreferences(TwitterConst.PREF_KEY,MODE_PRIVATE);

        if (pref.getString("status", "").equals("available")) {
              Toast.makeText(IndexActivity.this, "already oauth. ", Toast.LENGTH_LONG).show();
        }
        else {
              Toast.makeText(IndexActivity.this, "disable oauth. ", Toast.LENGTH_LONG).show();
        }

        Button tweetBotton = (Button) findViewById(R.id.tweet);
        tweetBotton.setOnClickListener(new OnClickListener() {
                     @Override
                     public void onClick(View v) {
                           if (pref.getString("status", "").equals("available")) {
                                  tweet();
                           }
                           else {
                                  authentication();
                           }

                     }
              });

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

              try {
                     accessToken = twitterOauth.getOAuthAccessToken(requestToken,intent.getExtras().getString(TwitterConst.PARAM_OAUTH_VERIFIER));
              } catch (TwitterException e) {
                     e.printStackTrace();
              }

       SharedPreferences pref = getSharedPreferences(TwitterConst.PREF_KEY,MODE_PRIVATE);
       SharedPreferences.Editor editor=pref.edit();
       editor.putString(TwitterConst.SUB_KEY_OAUTH_TOKEN,accessToken.getToken());
           editor.putString(TwitterConst.SUB_KEY_OAUTH_TOKEN_SECRET,accessToken.getTokenSecret());
       editor.putString("status","available");
       editor.commit();

       Toast.makeText(IndexActivity.this, "OAuth end.", Toast.LENGTH_LONG).show();

       finish();
    }

    private void authentication() {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        builder.setOAuthConsumerKey(TwitterConst.CONSUMER_KEY);
        builder.setOAuthConsumerSecret(TwitterConst.CONSUMER_SECRET);
        Configuration configuration = builder.build();

        twitterOauth = new OAuthAuthorization(configuration);
        twitterOauth.setOAuthAccessToken(null);

        try {
                     requestToken = twitterOauth.getOAuthRequestToken(TwitterConst.CALLBACK_URL);
              } catch (TwitterException e) {
                     e.printStackTrace();
              }

        Intent intent = new Intent(IndexActivity.this, LoginTwitterActivity.class);
        intent.putExtra("auth_url", requestToken.getAuthorizationURL());

        IndexActivity.this.startActivityForResult(intent, 1);
    }

    private void tweet(){
         String oauthToken       = pref.getString("oauth_token", "");
         String oauthTokenSecret = pref.getString("oauth_token_secret", "");

         ConfigurationBuilder builder = new ConfigurationBuilder();
         builder.setOAuthConsumerKey(TwitterConst.CONSUMER_KEY);
         builder.setOAuthConsumerSecret(TwitterConst.CONSUMER_SECRET);
         builder.setOAuthAccessToken(oauthToken);
         builder.setOAuthAccessTokenSecret(oauthTokenSecret);
         Configuration config = builder.build();

         Twitter twitter = new TwitterFactory(config).getInstance();
      try {
                     twitter.updateStatus("※ここに記載した内容がツイートされます。※");
              } catch (TwitterException e) {
                     e.printStackTrace();
              }
    }
}

LoginTwitterActivity.java

public class LoginTwitterActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);

        WebView webView = (WebView)findViewById(R.id.login);
                webView.setWebViewClient(new TwitterWebViewClient());
        webView.loadUrl(this.getIntent().getExtras().getString("auth_url"));
    }

    private class TwitterWebViewClient extends WebViewClient {
           public void onPageFinished(WebView view, String url) {
         super.onPageFinished(view, url);

         if (url != null && url.startsWith(TwitterConst.CALLBACK_URL)) {

           String[] urlParameters = url.split("\\?")[1].split("&");
           String oauthToken      = "";
           String oauthVerifier   = "";

           if (urlParameters[0].startsWith(TwitterConst.PARAM_OAUTH_TOKEN)) {
             oauthToken = urlParameters[0].split("=")[1];
           }
           else if (urlParameters[1].startsWith(TwitterConst.PARAM_OAUTH_TOKEN)) {
             oauthToken = urlParameters[1].split("=")[1];
           }
           if (urlParameters[0].startsWith(TwitterConst.PARAM_OAUTH_VERIFIER)) {
             oauthVerifier = urlParameters[0].split("=")[1];
           }
           else if (urlParameters[1].startsWith(TwitterConst.PARAM_OAUTH_VERIFIER)) {
             oauthVerifier = urlParameters[1].split("=")[1];
           }

           Intent intent = getIntent();
           intent.putExtra(TwitterConst.PARAM_OAUTH_TOKEN, oauthToken);
           intent.putExtra(TwitterConst.PARAM_OAUTH_VERIFIER, oauthVerifier);
           intent.putExtra("status","available");

           setResult(Activity.RESULT_OK, intent);
           finish();
         }
      }
   }
}

一応できた。