もう猫も杓子もTwitterな昨今いかがお過ごしでしょうか。
というわけですごい単純なTwitterClientを作成したいと思います。
ちなみにこちらの「きしだのはてな」さんのサンプルをす~っごく参考にしました。
http://d.hatena.ne.jp/nowokay/20091030
また、
「ところで、HTMLの最初のほうに変更がないと、loadDataしても画面が更新されないのはなんでなんだぜ?」
と発言されていますが、本当になぜなんだぜ?
ちなみに
- キャッシュかな?と思い、WebView.clearCache でキャシュをクリアするも意味なし
- 描画に更新かければいいのかと考え、WebView.postInvalidate()を呼ぶも意味なし
- WebView.loadData を2回呼ぶと更新される・・・。←とりあえず暫定で採用
- きしだのはてなさんのサンプルのように、上のほうの文字列を変更する
わけわかんね。
layout/main.xml
ボタンを2つ並べて表示するために、TableLayoutを使用。
また、2つボタンのサイズを統一するためにlayout_weightの値をそろえる。
AndroidManifest.xml ネットに繋ぐ前提となるので
・<uses-permission android:name="android.permission.INTERNET"></uses-permission>
を追加
Main.java
package com.omokageru.ak.twitter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.MultiAutoCompleteTextView.Tokenizer;
public class Main extends Activity {
private Button updateButton;
private Button reloadButton;
private EditText updateEdit;
private WebView webView;
private DefaultHttpClient httpClient;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
updateButton = (Button) findViewById(R.id.UpdateButton);
// ボタン押下時の処理
updateButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO 自動生成されたメソッド・スタブ
// 通信を伴うので別スレッドで
new Thread(){
@Override
public void run() {
// TODO 自動生成されたメソッド・スタブ
updateButton.setClickable(false);
reloadButton.setClickable(false);
String str = updateEdit.getEditableText().toString();
UpdateTwitter(str);
reloadButton.setClickable(true);
updateButton.setClickable(true);
}
}.start();
}
});
reloadButton = (Button) findViewById(R.id.ReloadButton);
reloadButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
// TODO 自動生成されたメソッド・スタブ
// 通信を伴うので別スレッドで
new Thread(){
@Override
public void run() {
updateButton.setClickable(false);
reloadButton.setClickable(false);
GetAndWriteHomeTimeLine();
reloadButton.setClickable(true);
updateButton.setClickable(true);
}
}.start();
}
});
updateEdit = (EditText) findViewById(R.id.UpdateEdit);
webView = (WebView) findViewById(R.id.twitter_web);
httpClient = new DefaultHttpClient();
Credentials cred = new UsernamePasswordCredentials( "Twitter User ID", "Password");//userとpassを
httpClient.getCredentialsProvider().setCredentials( new AuthScope("twitter.com", 80), cred);
GetAndWriteHomeTimeLine();
}
/**
* Twitterへつぶやく
* @param str
* 投稿内容
*/
private synchronized void UpdateTwitter( String str){
try {
// パラメータstatus=hoge でhogeを発言
// status は必須パラメータ
HttpPost post = new HttpPost( "http://twitter.com/statuses/update.json?status=" + str);
// 一応これで発言するはず
HttpResponse response = httpClient.execute(post);
// 失敗時の処理
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
return;
}
// ここからの描画はなぜか利かない・・・
GetAndWriteHomeTimeLine();
} catch (ClientProtocolException e) {
// TODO 自動生成された catch ブロック
} catch (IOException e) {
// TODO 自動生成された catch ブロック
}
}
/**
* friend_timelineは将来廃止予定らしいので home_timeline を取得し表示。<br />
* http://d.hatena.ne.jp/nowokay/20091030 を参考にしました。
*/
private synchronized void GetAndWriteHomeTimeLine(){
try {
// webView.clearCache(false);
HttpGet get = new HttpGet( "http://twitter.com/statuses/home_timeline.json");
// これで取得するはず
HttpResponse response = httpClient.execute(get);
// 失敗時の処理
if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){
return;
}
//解析と出力
//サーバーからのデータを取得
InputStream is = response.getEntity().getContent();
InputStreamReader isr = new InputStreamReader(is);
StringWriter strin = new StringWriter();
BufferedReader buf = new BufferedReader(isr);
for(String line; (line = buf.readLine()) != null;){
strin.write(line);
}
buf.close();
isr.close();
is.close();
//出力準備
StringWriter strout = new StringWriter();
PrintWriter out = new PrintWriter(strout);
out.println("<html><head><title>Twitter testapites</title></head>");
out.println("<body>");
//JSONデータからタイムラインを取得してHTMLを生成
JSONTokener token = new JSONTokener(strin.toString());
JSONArray arr = new JSONArray(token);
for(int i = 0; i < arr.length(); i++){
JSONObject obj = arr.getJSONObject(i);
JSONObject user = obj.getJSONObject("user");
out.println("<div style='border-bottom: 1px solid #888888'>");
out.println("<img style='width:48px; height:48px;' src='" + user.get("profile_image_url") + "' align='left'>");
out.println("<bold><font color='#6666ff'>" + user.getString("screen_name") + "</font></bold><br />" );
out.println(obj.get("text") + "<br clear='all' />");
// ここで出力を確認しているが、発言内容が含まれているにもかかわらず、
// loadData一回ではなぜか更新されない。
Log.i("t_test", "" + obj.get("text"));
out.println("</div>");
}
out.println("</body></html>");
strin.close();
out.close();
// 二回呼び出すと反映される・・・
// invalidate() の意味は??
webView.loadData(strout.toString(), "text/html", "utf-8");
webView.loadData(strout.toString(), "text/html", "utf-8");
strout.close();
// 描画更新
// 本体スレッドからの呼び出しではない場合に備えpostInvalidateを使用。
// webView.postInvalidate();
// Log.i("t_test", "Invalidate");
} catch (ClientProtocolException e) {
// TODO 自動生成された catch ブロック
} catch (JSONException e) {
// TODO 自動生成された catch ブロック
} catch (IOException e) {
// TODO 自動生成された catch ブロック
}
}
}
一応発言と描画には synchronized をつけているので、重複して呼び出して落ちるってことはないと思いますが、念のため作業中はボタンを無効化しています。
失敗時の処理はめんどいので放置。
こんなソースを参考にする場合は、その辺はきっちりやることをお勧めします。
ちなみにhttp://twitter.com/statuses/home_timeline.json をたたくとこんな感じで返ってきます。
twitter_json_sample.txt
動かすとこんなかんじ。
起動時に取得に行きます。
発言すると、発言がきちんと反映
とりあえずメデタシメデタシ


0 件のコメント:
コメントを投稿