/* * ・ 画像データをhttpアクセスでダウンロード。 * ・ スクラッチパッドに書き込む。 * ・ スクラッチパッドから画像を読み込んで表示確認。 * …するだけのiアプリ。 * * DoJa 3.0 プロジェクト設定で、指定したのは以下の項目 * * AppName = IappTestSpLoad * PackageURL = http://localhost:80/i/spload/IappTestSpLoad.jar * AppClass = spload.SpLoad * SPsize = 204800 * UseNetwork = http * LaunchByBrowser = any * UseBrowser = launch * */ package spload; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.microedition.io.Connector; import com.nttdocomo.io.ConnectionException; import com.nttdocomo.io.HttpConnection; import com.nttdocomo.ui.Canvas; import com.nttdocomo.ui.Dialog; import com.nttdocomo.ui.Display; import com.nttdocomo.ui.Graphics; import com.nttdocomo.ui.IApplication; import com.nttdocomo.ui.Image; import com.nttdocomo.ui.MediaImage; import com.nttdocomo.ui.MediaManager; public class SpLoad extends IApplication { public void start() { Main m = new Main(); m.setSoftLabel(Main.SOFT_KEY_2, "終了"); Display.setCurrent(m); } } class Main extends Canvas implements Runnable { static final int FPS = 10; static final int IMGPAK_MAX = 7; // 画像パックデータ 総数 static final int CHKCODE = 0x29E5; // 画像パックに入ってるチェックサム static final String IMGFNAME = "imgdata"; // 画像パックデータ ファイル名 static final String IMGFNEXT = ".pak"; // 画像パックデータ 拡張子名 static final int IMG_STOR_OFFSET = 1024; // SP上の画像読み込み位置 static final int SLEEP_VALUE = 1000 / FPS; static final int FONTSIZE = 12; Thread tm; int step; int img_num_max; // 画像数 int remaincounter; // ロードデータ残り数 int dispnum; // 表示する画像ナンバー Image[] gifimg; String error; String status; // キー入力値 int key; int keyrel; int keytrg; public Main() { step = 0; error = ""; status = ""; remaincounter = IMGPAK_MAX; tm = new Thread(this); tm.start(); } public void run() { repaint(); mainInit(); // メインループ while (true) { try { Thread.sleep(SLEEP_VALUE); } catch (InterruptedException e) { e.printStackTrace(); break; } int keyold = key; key = this.getKeypadState(); keyrel = (keyold | key) ^ key; keytrg = (keyold ^ key) & key; if ((keytrg & (1 << Display.KEY_LEFT)) != 0) { dispnum--; if (dispnum < 0) { dispnum = img_num_max - 1; } } if ((keytrg & (1 << Display.KEY_RIGHT)) != 0) { dispnum++; if (dispnum >= img_num_max) { dispnum = 0; } } repaint(); } } public void mainInit() { int dlfg = 0; if (readSpDataShort(IMG_STOR_OFFSET + 2) == CHKCODE) { // checksum が SP に書かれてた。ダウンロード済みとする。 System.out.println("データ読み込み済み"); remaincounter -= IMGPAK_MAX; dlfg = 1; } if (dlfg == 0) { // まだデータをダウンロードしてないので、ダウンロードする。 if (downloadDataWriteSpAll() != 0) { System.out.println("データ読み込み完了"); dlfg = 1; } else { displayErrorDialog(error + "ネットからデータを読み込めませんでした。時間を変えて起動してみてください。"); } } if (dlfg != 0) { // データはダウンロード済み testWriteSp(); // スクラッチパッドに書き込みテスト testReadSp(); // スクラッチパッドから読み込みテスト img_num_max = readSpDataShort(IMG_STOR_OFFSET); gifimg = new Image[img_num_max]; remaincounter = img_num_max; loadImageFromSp(); // スクラッチパッドから画像を読み込み dispnum = 0; step++; } } public void processEvent(int w_type, int w_param) { if ((w_type == Display.KEY_PRESSED_EVENT) && (w_param == Display.KEY_SOFT2)) { IApplication.getCurrentApp().terminate(); // アプリ終了 } } // 画面描画処理 public void paint(Graphics g) { g.lock(); g.clearRect(0, 0, getWidth(), getHeight()); if (step == 0) { g.drawString("データ読み込み中", 72, 100); g.drawString("残り" + remaincounter + "個", 96, 100 + (FONTSIZE * 1)); g.drawString(status, 4, 240 - (FONTSIZE * 2)); } else { g.drawImage(gifimg[dispnum], 0, 0); g.drawString("Load End. Disp = " + dispnum, 93, 240 - (1 * FONTSIZE)); } g.unlock(true); } // -------------------------------------------------- // 動作確認用 public void testWriteSp() { if (writeSpData(573, 512) < 0) { System.out.println("write SP Failure."); } } public void testReadSp() { int res = readSpDataInt(512); System.out.println("read SP : " + res); } // 動作確認用 ここまで // -------------------------------------------------- // httpサーバから画像データをダウンロード。scratchpad に書き込み。 public int downloadDataWriteSpAll() { int result = 1; int ofs = IMG_STOR_OFFSET; for (int i = 0; i < IMGPAK_MAX; i++) { String fn = IMGFNAME + i + IMGFNEXT; int size = downloadSpData(fn, ofs); if (size > 0) { // ロード成功 System.out.println("Load " + fn + "/size=" + size); remaincounter--; repaint(); } else { // ロード失敗 System.out.println("Load Failure. " + fn); result = 0; break; } ofs += size; } return result; } // 分割されてるデータを一つだけダウンロード public int downloadSpData(String filename, int offset) { System.gc(); // URL取得 String url = IApplication.getCurrentApp().getSourceURL() + filename; System.out.println(url); int size = 0; error = ""; byte[] data = null; HttpConnection con = null; InputStream in = null; OutputStream spout = null; try { con = (HttpConnection) Connector.open(url, Connector.READ, true); con.setRequestMethod(HttpConnection.GET); con.connect(); // 接続 int response = con.getResponseCode(); if (response == HttpConnection.HTTP_OK) { // 正常に接続できた in = con.openInputStream(); spout = Connector.openOutputStream("scratchpad:///0;pos=" + offset); int c; while ((c = in.read()) != -1) { spout.write(c); // sp に書き込み size++; } } else { error += "Response " + response + "\n"; } } catch (ConnectionException ce) { error += ce.toString() + "\n"; error += "status = " + ce.getStatus() + "\n"; size = 0; } catch (IOException ie) { error += ie.toString() + "\n"; size = 0; } catch (Exception e) { error += e.toString() + "\n"; size = 0; } finally { try { if (spout != null) { spout.close(); spout = null; } if (in != null) { in.close(); in = null; } if (con != null) { con.close(); con = null; } } catch (Exception e) { spout = null; in = null; con = null; } } if (!error.equals("")) { System.out.println(error); } return size; } // scratchpad に書き込み public int writeSpData(int value, int offset) { int result = 0; try { DataOutputStream dos = Connector.openDataOutputStream("scratchpad:///0;pos=" + offset); dos.writeInt(value); dos.close(); result = 4; } catch (IOException e) { System.out.println("SP write error : " + e.toString()); } return result; } // scratchpad から読み込み public byte[] readSpData(int offset, int size) { byte[] str = new byte[size]; try { InputStream in = Connector.openInputStream("scratchpad:///0;pos=" + offset + ",length=" + size); in.read(str, 0, size); in.close(); } catch (IOException e) { System.out.println("SP read error : " + e.toString()); return null; } return str; } // scratchpad から読み込み(int) // MSB がどうなるかは怪しい。 public int readSpDataInt(int offset) { byte[] str = readSpData(offset, 4); long result = 0; result += (((long) str[0]) << 24) & 0x0ff000000; result += (((long) str[1]) << 16) & 0x0ff0000; result += (((long) str[2]) << 8) & 0x0ff00; result += (((long) str[3])) & 0x0ff; return (int) result; } // scratchpad から読み込み(short) public short readSpDataShort(int offset) { byte[] str = readSpData(offset, 2); long result = 0; result += (((long) str[0]) << 8) & 0x0ff00; result += (((long) str[1])) & 0x0ff; return (short) result; } // スクラッチパッドからgif画像を1ファイル読み込む public Image loadOneImageFromSp(int num) { Image img; int imgtotal = readSpDataShort(IMG_STOR_OFFSET); int hofs = IMG_STOR_OFFSET + 4 + (num * 8); int ofs = readSpDataInt(hofs); int size = readSpDataInt(hofs + 4); System.out.println(num + "/" + (imgtotal - 1) + "/o=" + ofs + "/sz=" + size); ofs += IMG_STOR_OFFSET; try { MediaImage mi = MediaManager.getImage("scratchpad:///0;pos=" + ofs + ",length=" + size); mi.use(); img = mi.getImage(); } catch (ConnectionException e) { System.out.println("ERR: Not Load Image " + num + ":" + e.toString()); displayErrorDialog("スクラッチパッドからの画像読み込みでエラーが発生しました。"); return null; } return img; } // スクラッチパッドから画像を読み込む public void loadImageFromSp() { for (int i = 0; i <= (img_num_max - 1); i++) { gifimg[i] = loadOneImageFromSp(i); System.gc(); remaincounter--; repaint(); } } // エラーダイアログ表示 public void displayErrorDialog(String str) { Dialog dlg = new Dialog(Dialog.DIALOG_ERROR, "エラー発生"); dlg.setText(str); dlg.show(); } }