2009年1月アーカイブ

flickrやtwitterなどのRESTの戻り値で、XMLだけでなく、JSONもサポートしている場合、

AndroidでもJSON形式のデータにアクセスできます。

具体的なサンプルソースコードは、以下のとおりです。 

JSONArray jsons = new JSONArray(json);
for (int i = 0; i < jsons.length(); i++) {
    JSONObject jsonObj = jsons.getJSONObject(i);
    id = jsonObj.getInt("id");
    text = jsonObj.getString("text");
    ...
}

まず、RESTで得られたInputStreamインスタンスを、
BufferedReaderやStringBuilderでString(上記ソースでは、json)に変換したら、

org.jsonパッケージのJSONArrayクラスに同文字列を渡してインスタンス化します。

すると、JSONObjectの配列が得られますので、順次アクセスして、目的の要素を取得できます。

org.apache.http.impl.clientパッケージのDefaultHttpClientクラスは、
HTTPクライアントを実装したクラスです。

インスタンス化するには、ThreadSafeClientConnManagerやHttpParamsのインスタンスを渡します。

具体的なサンプルコードは、以下のとおりです。

final HttpClient httpClient = new DefaultHttpClient(
    new ThreadSafeClientConnManager(httpParams, schemeRegistryRegistry),
    httpParams);

 インスタンス作成後、HTTPリクエスト(GETやPUTなど)を発行するには、DefaultHttpClient.execute()を呼び出します。

具体的なサンプルコード(Twitterのpublic_timeline取得)は、以下のとおりです(一部、例外処理を省略して抜粋しています)。

final Uri.Builder uriBuilder = new Uri.Builder();
uriBuilder.path("/statuses/public_timeline.xml");

HttpEntity httpEntity = null;

final HttpResponse httpResponse = httpClient.execute(
    new HttpHost("twitter.com", 80),
    new HttpGet(uriBuilder.build().toString()));

if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
    httpEntity = httpResponse.getEntity();
    final InputStream in = httpEntity.getContent();
    final XmlPullParser parser = Xml.newPullParser();
    try {
        parser.setInput(new InputStreamReader(in));
        // ・・・XMLを解析する処理・・・
    } catch (XmlPullParserException e) {
    }
}

順を追って説明すると、

DefaultHttpClient.execute()の第1引数には、
org.apache.httpパッケージのHttpHostインスタンスを渡す必要があるため、

new HttpHost(ホスト名、ポート名);

でインスタンス化しています。
ここでのホスト名とは、たとえば、Twitterのタイムラインパスである

http://twitter.com/statuses/public_timeline.xml

の場合、twitter.comの部分です。

また、DefaultHttpClient.execute()の第2引数には、
org.apache.http.client.methodsパッケージのHttpGetインスタンスを渡します。

※同パッケージには、他にもHttpPut、HttpPost、HttpDeleteがあります

HttpGetに渡す引数は、uri文字列ですが、
これは、Uri.Builderクラスから作成できます。

ここでのuriとは、先の例で言うと、/statuses/public_timeline.xmlの部分を指します。

※さらに?key1=value1&key2=value2などを渡すには、appendしていけばよいです

リクエストの戻り値は、org.apache.httpパッケージのHttpResponseクラスであり、HttpResponse.getEntity()を呼び出し、

同(org.apache.http)パッケージのHttpEntityを得た後、
HttpEntity.getContent()を呼び出すと、InputStreamインスタンスが得られます。

あとは、XMLをパースするなどしていけばよいです。

org.apache.http.conn.scheme.SchemeパッケージのSchemeRegistryクラスは、
"http"や"https"のようなプロトコルスキームを登録するクラスです。

※このクラスは、DefaultHttpClientクラスを使用する際に必要になります

インスタンス作成後、スキームを登録するには、SchemeRegistry.register()を呼び出します。

具体的なサンプルコードは、以下のとおりです。

final SchemeRegistry schemeRegistryRegistry = new SchemeRegistry();

schemeRegistryRegistry.register(
    new Scheme(HttpHost.DEFAULT_SCHEME_NAME, // "http"
        PlainSocketFactory.getSocketFactory(),
        80));    // ポート番号

 ちなみに、SchemeRegistry.register()の引数には、
同(org.apache.http.conn.scheme.Scheme)パッケージのSchemeインスタンスを渡す必要があるのですが、
上記のような引数を渡せば、インスタンス化できます。

※PlainSocketFactoryも、同(org.apache.http.conn.scheme.Scheme)パッケージのクラスです

org.apache.http.paramsパッケージのBasicHttpParamsクラスは、
HTTPバージョンやキャラクタセットなどのHTTPプロトコルパラメータを保持するクラスです。

※このクラスは、SingleClientConnManager/ThreadSafeClientConnManagerや、DefaultHttpClientクラスを使用する際に必要になります

インスタンス作成後、パラメータを設定するには、
同(org.apache.http.params)パッケージのHttpProtocolParamsクラスを使用します。

具体的なサンプルコードは、以下のとおりです。

final HttpParams httpParams = new BasicHttpParams();

HttpProtocolParams.setVersion(httpParams, HttpVersion.HTTP_1_1);    // HTTP 1.1
HttpProtocolParams.setContentCharset(httpParams, HTTP.UTF_8);        // UTF-8

ちなみに、
HTTPバージョンは、org.apache.httpパッケージのHttpVersionクラスの定数である
HTTP_0_9、HTTP_1_0、HTTP_1_1(通常はコレ)を利用できます。

また、
キャラクタセットには、org.apache.http.protocolパッケージのHTTPクラスの定数である
DEFAULT_CONTENT_CHARSET("ISO-8859-1")や、UTF_8("UTF-8")
などを利用できます。

※RESTサービスの多く(Flickr、Picasa、YouTube、Twitter)は、UTF-8です

お勧めのAndroidサンプルアプリケーションは、apps-for-androidです。

入手先は、こちら(http://code.google.com/p/apps-for-android/)。
※Project ownersは、Google先生です。

apps-for-androidには、いくつかのプロジェクトが含まれているのですが、
この中でも超お勧めが、Photostreamという、Android版Flickrクライアントです。

Androidで、Flickr、Picasa、TwitterとかRESTクライアントを作ろうとう方々には、大変よい入門書(ソースコード)になると思います。

ちなみにソースコードは、リンク先のSourceタブのsvnパスを、SVNクライアントでダウンロードできます。
※Windowsの場合、TortoiseSVNがお勧め) 

startActivity()でアクティビティを開始したが、

Suspended exception ActivityNotFoundException

と表示される場合、

AndroidManifest.xmlのApplication Nodesに、

目的のActivityが追加されていない可能性があります。 

対処するには、

  1. Eclipseの[PackageExplorer]から、[AndroidManifest.xml]をダブルクリック
  2. [AndroidManifest.xml]の編集画面下の[Application]タブをクリック
  3. [Add]ボタンをクリック
  4. [Create a new element at the top level, in Application.]で、[Activity]など追加したい要素が選択された状態で、[OK]ボタンをクリック
  5. (画面右下1/4の領域に表示される)Name*の右にある[Browse]ボタンをクリック
  6. [Select class name for element Application]下のリストから目的のクラスをクリック

AndroidManifest.xmlファイルを直接編集する場合、

<application></application>の間に

<activity android:name="クラス名"></activity>

を挿入すればOKです。

[Android] SimpleDateFormat

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

日時文字列からDateクラスのインスタンスを得るには、DateUtils.parseDate()を使用する方法以外にも、SimpleDateFormat.parse()を使用しても同様のことができます(こちらの方がお勧めかも)。

また、Dateクラスのインスタンスから任意の日時文字列に変換するには、SimpleDateFormat.format()を使用します。

下記に相互変換したサンプルコードを記載しておきます。

String inDate = "Sat, 10 Jan 2009 00:00:00 +0900";
String outDate = null;

SimpleDateFormat inFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
SimpleDateFormat outFormat = new SimpleDateFormat("yyyy/MM/dd");
Date date = null;

try {
    date = inFormat.parse(inDate);
} catch (ParseException e) {
}

outDate = outFormat.format(date); // 結果は、"2009/01/10"

Java言語の配列の書き方は、以下のとおり。

int[] a = {0, 1, 2};
int[] b = new int[] {0, 1, 2};
int[] c = new int[3];
c[0] = 0;
c[1] = 1;
c[2] = 2;

※色々な言語を行き来していると忘れてしまいます。。。現在、C++、AS3、Javaを並行して作業しているので・・・という言い訳。。。

[Android] DateUtils.parseDate

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

日時文字列からDateクラスのインスタンスを得るには、DateUtils.parseDate()を使用します。

ソースコードサンプルは、以下のとおりです。

String dateString = "Sat, 10 Jan 2009 00:00:00 +0900";
String pattern[] = {DateUtils.PATTERN_RFC1123};
Date date = null;
try {
    date = DateUtils.parseDate(dateString, pattern);
} catch (DateParseException e) {
}

DateUtilsには、下記の文字列定数がありますので、 変換元のフォーマットが一致する場合には、定数を指定するだけで利用できますが、そうでない場合にも、HHやmmなどで、独自のフォーマット文字列を書けば利用できます。

  • PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy"
  • PATTERN_RFC1036 = "EEEE, dd-MMM-yy HH:mm:ss zzz"
  • PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"

※EEEは、曜日。zzzは、タイムゾーン。

Androidでサポートしている画像フォーマットは、以下のとおり。

  • Bitmap(BMP)
  • JPEG(JPG)
  • PNG
  • GIF

静的にリソースに組み込む場合には、res/drawableに画像を配置して、ImageView.srcにセットすれば表示できる。

※Googleさんの公式ドキュメントは、こちら
 ここでは、PNGが推奨(preferred)で、それ以外は、非推奨(discouraged)と記載されている。

また、URL(http://~)から動的に読み込む場合には、(BufferedInputStream,ByteArrayOutputStream,BufferedOutputStreamなどで)読み込んだbyte配列をBitmapFactory.decodeByteArray()にセットすることでBitmapが得られるので、ImageView.setImageBitmap()にセットすれば表示できる。

※Googleさんの公式ドキュメントでいうと、android.graphicsパッケージ内のBitmapBitmapFactoryのあたり。

ちなみに駄目元でTIFF(TIF)を試してみたら、やっぱり駄目でした。

<<前のページへ 123

Android Advent Calendar 2011

2012年2月

      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