スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

J2ME(S!アプリ)開発日記 その6

エミュレータの開発が進み、そろそろ実機でテストする準備をしなければ、と思い、アプリゲットに作者登録した。

J2MEのアプリケーションは最終的には、JADファイルとJarファイルのセットで配布する。Jadファイルには、Midletの様々な属性を記述する。ここを間違えると、ダウンロードできなかったり、起動できなかったり、正しい動作ができなかったりするので重要だ。
特に、MIDxlet-API: JSCL-1.4.2
の記述は本当に重要だった。

で、そのJadとJarファイルだが、通常のWebサーバに置いてもダウンロードできない。JadもJarも正規の署名がされていなければ、あるいはキャリアの認めたURLでなければ、キャリアのネットワークがブロックするからだ。メモリカードに入れても同じ。端末が不正なアプリとして認識しない。また端末に保存されていても、SIMカードを入れ替えてしまうと認識できない。あくまでもダウンロードしたユーザにしか使えない。こういういろいろな制約がある。

なので、キャリアが認めたWebサーバ、アグリゲータに登録する必要がある。
アプリゲットに作者登録を申し込んだら、すぐに受理されて使えるようになった。しかし、外部との通信を行うアプリケーションは登録できない。セキュリティ上の問題でエラーになって、アップロードできない。なので、StorageConnectionを使う処理は実機では試すことができず、それを省いてUIの確認だけをまず実機でした。

外部との通信が可能なアプリを登録するには、オフィシャル作者登録が必要になる。これにはオンラインではなく、紙ベースで個人の証明書類とともに提出して審査してもらう。
送付後、メールでいろいろ質問が来た。公開の意志と何を作るのか。それに答えたらまた返ってきてなぜオフィシャルである必要があるのかと。
うーん、こんなの最初から聞いてくれよ。条件があるならそれをもっときちんと明記してくれよと思いながらも、丁寧に返答。ここで蹴られては、今までの実装が無駄になる。
まあ、自分ひとりで使う分には、アプリの中に辞書ファイルを含めてしまってダウンロードすればできてしまうことだが。
結局、審査に一週間かかりようやく受理。

早速実機での確認だと、エミュレータ上で完成したアプリをアップロード。エラーなくきちんとアップロードできる。
実機でダウンロードしようとすると、「不正データのためダウンロードできません」となって門前払い。アグリゲータのチェックを通っているのに何でと思った。Jadファイルで余計な項目があるからだろうと思い削ったが駄目。やっぱこれでもセキュリティ上の問題でStorageConnectionは駄目なのだろうかと思ったが、案外簡単なところにあった。
MIDxlet-ScreenSize: 480,588
としていたのが駄目で、
MIDxlet-ScreenSize: 240,260
としたらダウンロードできた。最初の奴は904SHの最大サイズなのだが。

OKかと思ったら、問題データが全く表示されない。サンプルは所定のディレクトリにコピーされているし、リスト表示もされている。ファイルのreadの仕方が悪いのかと思い、Resourceを読むのと同じようにavailable()を使うのをやめたが、それでも駄目。
Other docuemntsの下にeitanというディレクトリを作り、そこに入れていたのだが、それがまずかったのだ。Other documentsの直下しか読めないのだ。なのになぜ作成し、書き出せるのかがよくわからないが。他のドキュメントを置いている場合は競合してしまうが、eitan.iniと.dicの拡張子の付いたファイルを扱うようにする。

しかし、読み込みと書き込みで、
「ユーザーデータ読み込み
個人情報取得を行います。よろしいですか?」
「ユーザーデータ書き込み
個人情報書込みを行います。よろしいですか?」
と聞いてくるのはうざく、毎回聞いてくる。終了時には、辞書ファイルと設定ファイル二つ書き込むため、二度聞かれる。eitan.iniはRecordStoreを使うべきかと思ったが、これは、単純。携帯でアプリを選択して、セキュリティレベルの設定を「表示しない」にすればよかった。

読み込みだが、エミュレータ上では、InputStream#availableが使えたものの、実機上では0が返ってしまう。1バイトずつreadしていたが非常に遅い。byte配列のBufferを1kぐらいにとって読めばいいかと思ったが、どうやってその後Stringにすりゃよかったっけとしばし黙考。でもそんな必要はなく、StorageConnection#getLengthでファイルのバイト数を取得できたので、そのバイト数のバイト配列を用意して、読み込みをしたら一気に早くなった。

しかし、問題はここから先だった。
携帯ではいろいろな割り込みイベントがある。着信、フリップを閉じる、電源ボタンを押す、など。こうするとJavaは強制的に停止させられる。そのとき、MidletのpauseApp()やdestroyApp()が呼ばれるので、必要であればそこに終了処理を記述しておく。
私は、pauseApp()で、辞書ファイルと設定ファイルを出力する処理を呼び出すようにしたが、うまくいかない。
フリーズして、5秒後に「エラーが発生しました」となって強制終了になる。
ファイルがきちんと保存できていることもあるが、たいていは途中で更新された内容は保存されていない。厄介なことにファイルが消えてしまうこともあった。

通常に終了処理をするときは、ファイルの保存は一瞬で終わる。pauseApp()の仕様として、5秒以内に終わらないと強制終了されるとあるのだが、そんなにかかるはずがない。

通常の操作で終了してくれることをユーザに期待したいが、PCと違い、ユーザの意志だけではどうにもならないところがある。電話がかかってくれば、携帯「電話」なので、電話が優先される。Vアプリ設定で着信時優先動作を変更できるが、これを毎回このアプリのためだけに設定するというのは期待できない。

仕方ないので、定期的に保存することにした。問題が数問進んだら保存。最後の数問の結果が保存されないのは致し方ないだろう。しかし、これでも問題があった。大きなファイルの場合、若干時間がかかるので、その間に、携帯を閉じるとファイルが消えてしまうことがあった。

そこで保存は別ファイルにして、終了処理でリネームすることにした。リネームの方が軽い処理だろうと思い込み、pauseApp()に入れたのだが、結局これも前と同じ結果となった。

別スレッドにして動かしたらうまく行くかもしれないと思い、pauseApp()はすぐに抜けるようにして別スレッドを走らせた。こうすると、強制終了する問題は回避できたものの、やはり、リネーム処理が完了しないまま終わってしまっている。たぶんJavaVM上で動いているスレッドすべてに停止命令がかかるのだろう。

そもそも5秒も待っていない。確かにフリーズして、エラー表示されるまで5秒だが、その間、Javaは自由に動ける状態にあるとは思えない。
結局、ファイルを読み込んだときに、backupを取ることにした。そして正常終了時に削除する。異常終了時の再起動時には表示しない。もしファイルが消えていれば、その他のフォルダを見て、~付きのファイルをリネームして手動で復旧する。

関連記事
スポンサーサイト

コメント

非公開コメント

プロフィール

dayan

Author:dayan
小職は、SE(システムエンジニア)を専門としておりますが、技術的な情報を中心に、それ以外に経済関連の日記、たわいもない日記も載せていきます。
[公式HPもよろしく!]

天気予報

-天気予報コム- -FC2-
リンク
ブロとも申請フォーム

この人とブロともになる

カテゴリー
最近の記事
ブログ内検索
最近のコメント
最近のトラックバック
RSSフィード
月別アーカイブ


上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。