Your SlideShare is downloading. ×

ネットワーク第6回

343
views

Published on

Androidアプリで作るTwitterClient

Androidアプリで作るTwitterClient

Published in: Technology

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
343
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 2013 ネットワーク第 6 回 目 OAuth 認証
  • 2. 1 はじめに Twitter の API のバージョンが 2012 年に 1.1 に変更になりました。 アプリケーション当たりのユーザ数制限や REST API の仕様変更など様々な変更が起 きています。 詳しくは以下記事を参考にしてください。 『Twitter API と開発者規約変更のインパクトまとめ:結局、 Twitter API 1.1 で何が変 わる? 5 つのポイント』 http://www.atmarkit.co.jp/ait/articles/1209/26/news120.html 下記から、Twitter4j を使った TwitterClient の作成を行います。 2 Twitter アプリの登録 1.1 Twitter devlopers にアクセス Twitter と連携するためには、Twitter にアプリ登録をする必要があります。 Twitter developers https://dev.twitter.com/ にアクセスし、サインアップします。 1.2 アプリケーションの選択 右上の自分のアイコンをクリックし、 『My applications』を選択する 1.3 アプリケーションを登録する 1.3.1 『Create a new application』をクリック 1.3.2 必要な項目を入力 『Name』 :アプリケーション名(自由) 『Description』 :ツイッタークライアントアプリの説明
  • 3. 『WebSite』 :自分の HP があれば、その URL を入力する。特になければ自分の Twitter の URL を入力する 『Callback URL』 :自分の HP があれば、その URL を入力する。特になければ自 分の Twitter の URL を入力する(入力は必須) 1.3.3 利用規約に同意 利用規約に同意にチェックボックスを付け、 CAPTCHA を入力して、 『Create your Twitter application』をクリックする 1.4 アプリケーションのアクセス制限を設定する アプリケーションから書き込みと読み込み権限を付けるようにする。 『Setting』 タブから 『Application type』 の欄に移動し、 『Read and Write』 を選択し、 画面一番下の『Update this Twitter application’s settings』をクリックする
  • 4. 1.5 OAuth 認証で使用するキーをメモ Android アプリからアクセスするために、 Detail に戻って、 Consumer key と Consumer secret をメモしておく 3 Android プロジェクトの作成 3.1 Android プロジェクトを新規で作成 アプリケーション名は自由で構いません。Target は自分の Android 端末や ADT のバ ージョンに合わせてください。また、Activity ファイルは MainActivity のままで構い ません。 3.2 [Twitter4j] http://twitter4j.org/ja/index.html のサイトにアクセスし、最新安定 バージョンをダウンロードします。 3.3 Zip ファイルを解凍して、lib/ディレクトリにある twitter4j-core-3.0.3.jar をプ ロジェクトの libs/ディレクトリに置きます。
  • 5. 3.4 TwitterUtils を新規クラスとして作成し、以下のプログラムを記述します。 package com.example.twitterclient; import twitter4j.Twitter; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; public class TwitterUtils { private static final String TOKEN = "token"; private static final String TOKEN_SECRET = "token_secret"; private static final String PREF_NAME = "twitter_access_token"; /** * Twitter インスタンスを取得します。 アクセストークンが保存されていれば自動 的にセットします。 * * @param context * @return */ public static Twitter getTwitterInstance(Context context) { String consumerKey = context.getString(R.string.twitter_consumer_key); String consumerSecret context.getString(R.string.twitter_consumer_secret); TwitterFactory factory = new TwitterFactory(); Twitter twitter = factory.getInstance(); twitter.setOAuthConsumer(consumerKey, consumerSecret); =
  • 6. if (hasAccessToken(context)) { twitter.setOAuthAccessToken(loadAccessToken(context)); } return twitter; } /** * アクセストークンをプリファレンスに保存します。 * * @param context * @paramaccessToken */ public static void storeAccessToken(Context context, AccessTokenaccessToken) { SharedPreferences preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); Editor editor = preferences.edit(); editor.putString(TOKEN, accessToken.getToken()); editor.putString(TOKEN_SECRET, accessToken.getTokenSecret()); editor.commit(); } /** * アクセストークンをプリファレンスから読み込みます。 * * @param context * @return */ public static AccessTokenloadAccessToken(Context context) { SharedPreferences preferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); String token = preferences.getString(TOKEN, null); String tokenSecret = preferences.getString(TOKEN_SECRET, null); if (token != null &&tokenSecret != null) { return new AccessToken(token, tokenSecret); } else { return null;
  • 7. } } /** * アクセストークンが存在する場合は true を返します。 * * @return */ public static booleanhasAccessToken(Context context) { return loadAccessToken(context) != null; } } R.string.twitter_consumer_key と R.string.twitter_consumer_secret が未定義なため、 エラーとなるが、それ以外は ctl+O でライブラリのインポートを行ってエラーを解消 する。 3.5 リソースファイルに追記 res/values/strings.xml ファイルを開いて、太字部分を追加する。Consumerkey と Consumer secret は TwitterDeveloper ページで取得した key を入力する。 <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">TwitterClient</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="twitter_consumer_key"> こ こ に Consumer key</string> <string name="twitter_consumer_secret"> こ こ に Consumer secret</string> </resources> 3.6 OAuth 認証画面を作成する ボタンを配置し、クリックすると OAuth 認証する Activity(ページ)を作成します。 3.6.1 レイアウトファイル作成する。 res/layout/activity_main.xml をコピペして「activity_twitter_oauth.xml」
  • 8. という名前を付けます。 3.6.2 ボタンを作成する activity_twitter_oauth.xml を開いて、テキストを削除し、代わりに Button を配置します。 3.6.3 ボタンに id を付ける activity_twitter_oauth.xml タ ブ を ク リ ッ ク し 、 xml フ ァ イ ル の 中 の android:id を『@+id/action_start_oauth』に変更します。 3.6.4 ボタンのテキストを変更する android:text を Button から『@string/twitter_oauth』に変更します。エラ ー に な っ た 場 合 は 、 Ctl+1 で 『 Create resource… 』 を 選 択 す る と 、 res/values/strings.xml に Button 名の定義が追加されます。 エラーにならな い人は、res/values/strings.xml ファイルに以下を追加します。 3.6.5 レイアウトファイルに戻って確認 ボタン名が反映されているかどうか確認します。
  • 9. 3.6.6 『TwitterOAuthActivity』クラスを作成 作成の際に、Activity クラスを継承することを忘れずに。 3.6.7 『TwitterOAuthActivity』に onCreate メソッドを追加する。 package com.example.twitterclient;
  • 10. import android.app.Activity; import android.os.Bundle; public class TwitterOAuthActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_twitter_oauth); } } 3.6.8 レイアウトファイルとアクティビティを紐付ける 作成した Activity ファイルとレイアウトファイルを紐付けます。 枠線の部分 を追加した Activity ファイル名に変更します。 3.6.9 『 MainActivity 』 ク ラ ス を 変 更 し て 、 Twitter 認 証 済 み で な け れ ば TwitterOAuthActivity を呼び出すようにする MainActivity.java を以下のように変更します。 (onCreate メソッドの中が変
  • 11. 更になっています) package com.example.twitterclient; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!TwitterUtils.hasAccessToken(this)) { Intent intent = new Intent(this, TwitterOAuthActivity.class); startActivity(intent); finish(); } } @Override public booleanonCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 3.6.10 AndroidManifest.xml を変更する Manifest ファイルに Activity の定義を追加します。Activity ファイルを追加した 場 合 は 、 Manifest フ ァ イ ル に も 追 記 が 必 要 で す 。 太 字 の 部 分 (<activity android:name=".TwitterOAuthActivity" />)を追加してください。
  • 12. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.twitterclient" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.twitterclient.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".TwitterOAuthActivity" /> </application> </manifest> 3.6.11 実行 Android アプリケーションを実行して、 以下のような画面が出れば OK です。
  • 13. 3.7 OAuth 認証を作成する ボタンがクリックされたら認証を開始して、認証開始後、アクセストークンを保存す るところまで作成します。 3.7.1 コールバックの設定 ブラウザでの OAuth 認証後にアプリにコールバックして戻ってくる仕組み を作成します。まず、AndroidManifest.xml の TwitterOAuthActivity の定 義を以下のように変更します。 <activity android:name=".TwitterOAuthActivity"
  • 14. 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:host="twitter" android:scheme="hoge" /> </intent-filter> </activity> <data android:host="twitter" android:scheme="hoge" /> のように、定義すると『hoge://twitter』という URL に反応するようになり ます。hoge の部分をスキーマと言いますが、http と記述してしまうと、通 常のブラウザでもアクティビティが反応してしまうため、アプリ独自の hoge というスキーマの場合のみアクティビティが起動するように設定して います。 3.7.2 コールバック URL の設定 コールバック URL『hoge://twitter』を res/values/strings.xml に定義しま す。 <string name="twitter_callback_url">hoge://twitter</string> 3.7.3 アクティビティに実装 ボ タ ン が 押 さ れ て か ら 、 OAuth 認 証 が 完 了 す る ま で の 処 理 を 『TwitterOAuthActivity』クラスに追加します。 public class TwitterOAuthActivity extends Activity { private String mCallbackURL; private Twitter mTwitter; private RequestTokenmRequestToken;
  • 15. @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_twitter_oauth); mCallbackURL = getString(R.string.twitter_callback_url); mTwitter = TwitterUtils.getTwitterInstance(this); findViewById(R.id.action_start_oauth).setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { startAuthorize(); } }); } /** * OAuth 認証(厳密には認可)を開始します。 * * @param listener */ private void startAuthorize() { AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { try { mRequestToken mTwitter.getOAuthRequestToken(mCallbackURL); return mRequestToken.getAuthorizationURL(); } catch (TwitterException e) { e.printStackTrace(); =
  • 16. } return null; } @Override protected void onPostExecute(String url) { if (url != null) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(intent); } else { // 認証失敗 } } }; task.execute(); } @Override public void onNewIntent(Intent intent) { if (intent == null || intent.getData() == null || !intent.getData().toString().startsWith(mCallbackURL)) { return; } String verifier = intent.getData().getQueryParameter("oauth_verifier"); AsyncTask<String, Void, AccessToken> task = new AsyncTask<String, Void, AccessToken>() { @Override protected AccessTokendoInBackground(String... params) { try { return
  • 17. mTwitter.getOAuthAccessToken(mRequestToken, params[0]); } catch (TwitterException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(AccessTokenaccessToken) { if (accessToken != null) { // 認証成功! showToast("認証成功!"); successOAuth(accessToken); } else { // 認証失敗。。 。 showToast("認証失敗。。"); 。 } } }; task.execute(verifier); } private void successOAuth(AccessTokenaccessToken) { TwitterUtils.storeAccessToken(this, accessToken); Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish(); } private void showToast(String text) { Toast.makeText(this, Toast.LENGTH_SHORT).show(); } } text,
  • 18. 3.7.4 パーミッションの追加 AndroidManifest.xml にインターネットへのアクセス許可をする権限を追 加します。 3.7.5 実行 実行して、ボタンをクリックし、OAuth 認証後、 『認証成功!』とトースト が表示されれば OK です。
  • 19. 3.8 タイムラインを表示する 3.8.1 MainActivity の親クラスを変更する タイムラインのような一覧を表示するために、ListView クラスを継承するように します。 public class MainActivity extends ListActivity { また、ListActivity クラスを継承した場合は、レイアウトファイルのセットが不要 になるので、以下を削除します。 setContentView(R.layout.activity_main); 3.8.2 MainActivity.java にリストを管理するクラスを作成する ListView で表示するデータは ArrayAdapter を継承したクラスで管理し、どう表 示するかもこの ArrayAdapter で定義します。 まず、 文字列だけ表示したいので、 以下のように String データを管理する ArrayAdapter を定義しましょう。 private class TweetAdapter extends ArrayAdapter<String> {
  • 20. public TweetAdapter(Context context) { super(context, android.R.layout.simple_list_item_1); } } 3.8.3 ArrayAdapter インスタンスを生成してセットする onCreate()メソッドで認証済みの場合は、ArrayAdapter インスタンスを生成して セットするようにします。ArrayAdapter インスタンスは、あとで他のメソッドか らも参照したいのでフィールド変数として定義します。 Twitter インスタンスもあとで他のメソッドから参照したいのでフィールド変数 として定義して、onCreate()メソッドで生成しておきます。 public class MainActivity extends ListActivity { private TweetAdaptermAdapter; private Twitter mTwitter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!TwitterUtils.hasAccessToken(this)) { Intent intent = new Intent(this, TwitterOAuthActivity.class); startActivity(intent); finish(); } else { mAdapter = new TweetAdapter(this); setListAdapter(mAdapter); mTwitter = TwitterUtils.getTwitterInstance(this); } } 3.8.4 タイムラインを取得して ListView に表示する タイムラインを取得して、 ListView に表示するメソッドを MainActivity クラスに 定義します。
  • 21. private void reloadTimeLine() { AsyncTask<Void, Void, List<String>> task = new AsyncTask<Void, Void, List<String>>() { @Override protected List<String>doInBackground(Void... params) { try { ResponseList<twitter4j.Status> timeline = mTwitter.getHomeTimeline(); ArrayList<String> list = new ArrayList<String>(); for (twitter4j.Status status : timeline) { list.add(status.getText()); } return list; } catch (TwitterException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(List<String> result) { if (result != null) { mAdapter.clear(); for (String status : result) { mAdapter.add(status); } getListView().setSelection(0); } else { showToast("タイムラインの取得に失敗しました。。"); 。 } } }; task.execute(); } private void showToast(String text) { Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
  • 22. } 3.8.5 アプリ起動時にタイムラインを取得する reloadTimeLine()メソッドを onCreate メソッドの中から呼び出すようにします。 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (!TwitterUtils.hasAccessToken(this)) { Intent intent = new Intent(this, TwitterOAuthActivity.class); startActivity(intent); finish(); } else { mAdapter = new TweetAdapter(this); setListAdapter(mAdapter); mTwitter = TwitterUtils.getTwitterInstance(this); reloadTimeLine(); } } 3.8.6 実行 実行してみて、タイムラインが表示されれば OK です。 4 演習 4.1 現在、ツイート本文のみの表示ですが、アイコン画像・名前・ユーザ名も表示す るように、 レイアウトファイルを作成してカスタムビューを表示するようにして ください。参考 URL:http://qiita.com/gabu/items/53857fcfa871b921af45 4.2 メニューアイコンを追加し、 当アプリからつぶやきが出来るようにしてください。 参考 URL:http://qiita.com/gabu/items/ac505aac0ccf2b3d0b42 5 参考文献 Android 再入門 - Twitter クライアントを作ってみよう– http://qiita.com/gabu/items/70689560618f8e67e726 Twitter4J http://twitter4j.org/ja/index.html