第14回 ネットからデータをダウンロードする

前回に引き続き,データをネットワーク経由でダウンロードするサンプルを取り上げていきたい。前回はスクラッチパッドを取り上げたので,今回はネットワークからのダウンロードだ。

【国内記事】 2001年4月27日 更新

iアプリのネットワーク接続

 iアプリではCLDC(Connected, Limited Device Configuration)(用語)に準拠したネットワーク入出力をサポートしているが,iモードの制約上,CLDCでできるネットワーク接続の全てが利用できるわけではない。

 ところで読者は,iモードの仕組みを,ご存知だろうか? もちろん知っているという読者が多いとは思うが,念のために説明を加えておこう。

 iモード端末(503iなどなど)は,実は直接インターネットにつながっているわけではない。iモードでインターネットに接続する際には,NTTドコモの設備内にあるゲートウェイが利用される。

 たとえば,読者がhttp://foo.bar.co.jpをiモード端末で見ようとすると,実際にはゲートウェイがインターネットを通じてhttp://foo.bar.co.jpにアクセスしてデータをダウンロードし,そのデータを読者の端末に送る仕組みになっている。

 iモード端末とNTTドコモのゲートウェイの間には独自のプロトコルが使われており,iモード端末自身がインターネットのプロトコルを処理しているわけではないという点がポイントだ。iモード端末はNTTドコモのゲートトウェイを介して擬似的にHTTPを処理できるが,それ以外のプロトコルは使えない。

 上記の理由で,iアプリでも,利用できるプロトコルはHTTP(またはセキュリティが追加されたHTTPS)プロトコルに制限されている。

 実際のネットワーク接続は,CLDCの汎用ネットワーク接続クラスConnectorを利用する。Connectorは前回のスクラッチパッドへのアクセスでも用いた。しかし,ネットワーク接続を行う場合は,スクラッチパッドのときに利用したopenInputStreamは利用せず,いったん接続の手続きを取るという手順が必要だ。

 まず,次のようにして接続オブジェクトを作成する。

HttpConnection htcon =
 (HttpConnection)Connector.open(
   "http://foo.bar.co.jp/FOO.DAT",
   Connector.READ,
   true );

 Connectorのopenメソッドは,CLDCではConnectionオブジェクト(汎用接続オブジェクト)を返すことになっているが,iアプリでは,Connectorを基底クラスに持つ(NTTドコモライブラリの)HttpConnectionというオブジェクトを返す仕様になっている。したがって,Connector.openの返り値をHttoConnectionに代入する際に,上記のように必ずキャストしよう。これを忘れてしまうとコンパイル時にエラーになる。

 openメソッドの第一引数は接続先URLだ。iアプリでは(先に述べた理由から)接続先に生のIPアドレスは使えないので注意してほしい。

 第2引数は接続モードを指定する。モードは次のとおりだ。

Connector.READ 読み出しモード
Connector.WRITE 書き込みモード
Connector.READ_WRITE 読み書きモード

 iアプリではHTTPしか使えないので,サーバからデータを取ってくる(GETメソッド)場合はREADモードを指定,CGIスクリプトやサーバウェアに対してデータを送信(POSTメソッド)する場合はREAD_WRITEモードを指定する。

 最後の引数は,タイムアウトを要求するかどうか。必要に応じてtrueかfalseを指定すればいい。

 さて,以上で接続オブジェクトhtconが得られるわけだが,接続〜データのダウンロードを行うには,ちょっとした作法に従っておく必要がある。接続に取りかかる前に,発行するメソッドと要求するドキュメントタイプを設定しなければならないのだ。次のようにする。

htcon.setRequestMethod(
   HttpConnection.GET);
htcon.setRequestProperty(
  "Content-Type","image/gif");

 まず,setRequestMethodで接続時に発行するメソッドを設定する。設定できるのは次の3つだ。

HttpConnection.GET GETメソッドに相当データを取得
HttpConnection.POST POSTメソッドに相当
HttpConnection.HEAD HEADメソッドに相当

次のsetRequestPropertyはHTTPリクエストのメッセージヘッダの指定だ。Content-typeかIf-Modified-Sinceを指定して,その値(上記ならimage/gif)を設定する。

 筆者がN503iで試したところでは,setRequestMethodやsetRequestPropertyは実行するメソッドがGETで,取得するデータがテキストの場合は省略しても動作するようだ。だが,ほかの機種で何が起こるかは不明なので,上記のような作法に従っておいたほうがよさそうだ。

 あとは接続して入力ストリームを取得,指定したURLからデータをダウンロードすればいい。

htcon.connect();
InputStream in =
  htcon.openInputStream();

という具合になる。InputStreamを通じてデータをダウンロードし終えたら,次のような終了処理も忘れないように。

in.close();
htcon.close();

スクラッチパッドの初期値

 前回に紹介したサンプルプログラム(http://gadget.mda.or.jp/iapp/ImageDemo.java)は,初めて起動されたときに限り,Webサーバーにアクセスして画像(GIFファイル)のデータをスクラッチパッドにダウンロードするように作られている。

 始めて起動されたかどうかを判定しているのは,checkIDというメソッドだ。判定の仕方は,いくつか考えたのだが,サンプルでは単純にスクラッチパッドの先頭にID番号(1バイトの49H……Iのアスキーコード)が書き込まれているかどうかで判断するようにしている。49Hが書かれていないなら初回起動と判断し,スクラッチパッドに49Hを書き込み,データをダウンロードするという手続きを踏んでいることはサンプルリストを読んでもらえば分かると思う。

 その手法に関して読者から「スクラッチパッドの初期値はどうなっているのか」という至極もっともな質問を頂いた。もし仮に,スクラッチパッドが初期化されずにiアプリに渡されるのなら,プログラムで設定したID番号(49H)が偶然,書き込まれていて誤動作するというケースが考えられるからだ。

 N503iでは,(筆者が調べた限り)スクラッチパッドは初期化されて渡されているように見えた。そのため,サンプルのような形にしたのだが,初期化されるかどうかは,iモード端末によって異なる可能性もありそうだ。

 したがって,初回起動かどうかを判定するときは,2バイト以上,できれば4バイトのIDコードで判断したほうが安全だろう。4バイト以上のIDにしておけば,そのIDが偶然に書き込まれている可能性は非常に低いので安心できると思う。

 さて,次回は少し実用的なプログラムの作成に取り組んでみたい。掲載は連休をはさんだ後になるので,ボリュームのあるサンプルを示せればと考えている。

関連記事
▼携帯向けJava,3社の違いは?
▼P503i,SO503iのiアプリに問題
▼Qualcomm,携帯電話向けプラットフォーム「BREW」発表──au端末に搭載
▼503iのベンチマーク結果をどう読むか?
▼iアプリの互換性は大丈夫なのか?
▼携帯電話はPCと逆方向に進化する?
▼iモード対応Javaを作るのに必要なものは?──NTTドコモ,仕様をついに公開
▼iモード対応Javaを作るのに必要なものは?──NTTドコモ,仕様をついに公開

[米田 聡,ITmedia]

Copyright © ITmedia, Inc. All Rights Reserved.



モバイルショップ

最新スペック搭載ゲームパソコン
高性能でゲームが快適なのは
ドスパラゲームパソコンガレリア!

最新CPU搭載パソコンはドスパラで!!
第3世代インテルCoreプロセッサー搭載PC ドスパラはスピード出荷でお届けします!!