| MIDP メモ | 内容が間違っている場合がありますのでご注意を。 |
|
□MIDPとは □準備 □サンプル実行 □SUNのサンプル実行 □J2ME Wireless Toolkit 1.0 □サンプル作成 □ネットワークを使った実行 □API Documentの作り方 □midp.exeの機能 □イメージの描画サンプル □データの保存 □メモ |
MIDPのサンプルゲーム(ソース付き)が参考になります。 現在の携帯Java情報やMIDPを使ったゲームの公開をされているJava-Mode! KVM全般については「KVM工房」の布留川氏のページへ。 AtsushiさんがMIDPについて丁寧に書かれています。 日本語では数少ないKVMでのPalmプログラミングが紹介されてるHolyCow!
< 2000/10/6 > < 2000/12/7 > < 2001/1/6 > |
MIDP(Mobile Information Device Profile)とは、J2ME(Java Micro Edition)のCLDC(Connected Limited Device Configuration)に属する、主に携帯電話等を対称とした仕様(Profile)の一つです。
と書くとやる気を無くしてしまいそうなのですが、要は「携帯電話でJavaする時に使うライブラリ仕様」のことです。(^^;;
MIDPでは「MIDlet」と言うアプリケーションの形式が定義されています。これは「WebのApplet」のような感じで、ダウンロード先のVMによって実行できる形式を統一することで、様々な環境で同じ動きを実現するためにあります。
注意:MIDletが実際に携帯アプリケーションの標準になるという保証はありません。(^^;;
現在(2000/10/6)SUNのJavaサイトからMIDP1.0正式版が無料でダウンロードできます。(登録が必要)
http://java.sun.com/products/midp/
実際に開発環境を整えるにはJDK1.2以上も必要です。
JDK1.2 : http://java.sun.com/products/jdk/1.2/ja/
JDK1.3 : http://java.sun.com/j2se/1.3/ja/download-windows.html
すみませんが、JDKのクラスパスの設定等は省略します。どうしても分からない場合はメールでも下さい。
MIDPをダウンロードし適当な場所に解凍したら(例:C:\midp-fcs)イメージを掴む為に早速私の用意したサンプルを実行してみます。(注意:ここでは、ネットワークから直接ダウンロードして実行するサンプルです。)
メモ帳などで以下の内容のバッチファイル(.bat)を作り、先ほど解凍したMIDPのフォルダ(c:\midp-fcs)へコピーし実行します。
bin\midp.exe -transient http://www.ngy1.1st.ne.jp/~takashi/MID/sample1.jad
上手く行けば下のような画面が出ます。

MIDP1.0正式版でのSUNのサンプル実行方法を formalin氏から教えて頂きました。
ありがとうございます。m(__)m
やり方は以下のようになります。
C:\midp-fcs\bin\midp.exe -classpath C:\midp-fcs\classes -descriptor C:\midp-fcs\src\example\run.jad
EarlyAccess版にもあったサンプルのほかにも「インベーダーゲーム」などが追加されています。
是非一度お試しあれ。(^^
2000/12/7:J2ME Wireless Toolkit 1.0正式版が公開されました。これはMIDPの開発をサポートするツールです。
ワンボタンで「コンパイル>検証>JAR化」までやってくれます。
また、実行、JADファイルの編集、各種トレースなども可能で、エミュレートできる機種にMinimumPhoneとPagerが追加されました。MIDPで使うAPIドキュメントが付属されていますので「API Documentの作り方」で作る必要が無くなりました。
以下からWindows専用でダウンロードできます。(JDK1.3以上も必要)
http://java.sun.com/products/j2mewtoolkit/
インストールされるのは、SUNのGUIを使ったJava開発環境「Forte」用モジュールと、上記のGUIツール「KVMエミュレータ」です。
KVMエミュレータの使い方は、「file>New Project...」で作られたフォルダ内にあるsrcフォルダの中にソースファイルを入れ、KVMエミュレータでビルド、実行するだけです。
・・・ちなみに今回の「preverify.exe」はやっとJARファイルが使えるようになったみたいです。(^^;;
では実際に作ってみます。
○ソース記述
MIDletを継承したクラスを作ります。定義しなければならないのはコンストラクタと、メソッド「startApp()」「pauseApp()」「destroyApp(boolean)」、さらにimplements CommandListenerの「commandAction(Command,Displayable)」です。
ソース内容としては以下のものとなります。(SUNのサンプルと同じ)
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class Sample1 extends MIDlet implements CommandListener {
private Command exitCommand;
private Display display;
public Sample1(){
display = Display.getDisplay(this);
exitCommand = new Command("Exit",Command.SCREEN,2);
}
public void startApp(){
TextBox textbox = new TextBox("Sample1","Hello World!",256,0);
textbox.addCommand(exitCommand);
textbox.setCommandListener(this);
display.setCurrent(textbox);
}
public void pauseApp(){
}
public void destroyApp(boolean unconditional){
}
public void commandAction(Command command,Displayable screen){
if(command==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}
ソースが完成したら次はコンパイルです。
例として、「C:\midp-fcs\project\sample」以下にSample1.javaがある場合のコンパイル方法を紹介します。
javac.exe -bootclasspath .;c:\midp-fcs\classes Sample1.java
これでクラスファイルができました。
J2MEではjavac.exeによって作成されたクラスファイルを2段階の検証を行い安全に実行しようとします。
その1段階目はMIDPの「preverify.exe」を使って実際に実行されるより以前に検証します。Win版は「c:\midp-fcs\build\win32\tools」にあります。
c:\midp-fcs\build\win32\tools\preverify.exe -classpath .;c:\midp-fcs\classes Sample1
成功すると「c:\midp-fcs\project\sample」フォルダに「output」というフォルダが新たに作られ、その中に検証済みのクラスファイルが移されます。
やっとこテスト実行です。(^^;;
実行には「c:\midp-fcs\bin」にある「midp.exe」を使います。これは未だ(2000/10/6)発売されていない「MIDP正式対応Java搭載携帯電話」の変わりをする「Java携帯エミュレータ」です。(^^;;
c:\midp-fcs\bin\midp.exe -classpath .;c:\midp-fcs\classes Sample
で実行できます。
実際にJavaを搭載した携帯電話が発売され、MIDletが実行できるようになったら、ネットワークを使いMIDletが携帯電話にダウンロードされ、必要な時に実行されるようになります。
現在(2000/6/17)はその環境がない為、先ほどの「midp.exe」を使い、ネットワーク上のMIDletが含まれるJARファイルをダウンロードし実行することができます。(しかできません)
また、MIDletアプリケーションの指定にはJAR形式で圧縮することの他に、JADという形式のファイルを作る必要があります。
初めのネットワークサンプルの実行で言うと、「sample1.jad」がそれに当たります。
MIDP1.0正式版ではこのJADファイルをJARに含める必要があります。
これは「ネットにあるJAD」の内容と「JARにあるJAD」とを比べて、そのバージョンなどを調べるようです。
JADファイルとは、Java Application Descriptor みたいな意味だと思います。(^^;;
実際はただのテキスト形式なのですが、書式としてはJARの「Manifest.mf」のような感じです。
MIDPに付属されるSUNのサンプル(HelloMIDlet)では以下のような内容になっています。
MIDlet-Name: HelloWorld MIDlet-Version: 1.0.0 MIDlet-Vendor: Sun Microsystems, Inc. MIDlet-Description: Sample Hello World MIDlet MIDlet-Info-URL: http://java.sun.com/j2me/ MIDlet-Jar-URL: http://127.0.0.1/hello.jar MIDlet-Jar-Size: 1020 MicroEdition-Profile: MIDP-1.0 MicroEdition-Configuration: CLDC-1.0 MIDlet-1: HelloWorld,, HelloMIDlet
これを参考にして私が書いたのが以下のものです。
MIDlet-Name: Sample1 MIDlet-Version: 0.1 MIDlet-Vendor: musashi MIDlet-Description: MIDlet Sample1 MIDlet-Info-URL: http://www.ngy1.1st.ne.jp/~takashi/MID/ MIDlet-Jar-URL: http://www.ngy1.1st.ne.jp/~takashi/MID/Sample1.jar MIDlet-Jar-Size: 1070 MicroEdition-Profile: MIDP-1.0 MicroEdition-Configuration: CLDC-1.0 MIDlet-1: Sample1,,Sample1
JADについての詳しい情報は私もまだ分かっていないのでこれで勘弁してください。(^^;;
一応、最後の行「MIDlet-1: Sample1,,Sample1」と言うのは、このJADファイルで使用するMIDletアプリケーションの登録のようで、この下に「MIDlet-2: Sample2,,Sample2」などとすると一つのJADファイルで複数のMIDletアプリケーションを登録することができるみたいです。(未確認)
また、「MIDlet-1: Sample1,,Sample1」のSample1で囲まれた「,,」の間にアイコン用のイメージファイルへのパスを入れることで、複数MIDletアプリケーションの選択画面で、そのアイコンが使えるようです。(SUNのサンプルをみる限り)
JADファイルを作ったらそれを検証済みクラスファイルと一緒にJARファイル化します。
製作したJADファイルをSample1.jadとした場合、
jar.exe cvmf Sample1.jad Sample1.jar *.class *.png
とすることで作成できます。
実際にネットワークから実行する場合は、JARファイルをJADで指定した場所にアップし、JADファイルも適当な場所にアップしておきます。
その場合の実行は、
c:\midp-fcs\bin\midp.exe -transient [ JADファイルのあるURL ]
とします。
2000/12/7:以下ではMIDPのソース(とCLDCのソース)を使ってAPI Documentを作成する方法を紹介しますが、J2ME Wireless Toolkit 1.0に正式なAPI Documentが付属されていますので、こちらを利用された方がいいと思います。
API Documentを作るソフトはもちろんJDKに付いてくるJavaDocです。これは結構便利なソフトなんで今まで使われていなかった方は是非他のところでも使ってみてください。
ドキュメントを作成する場所を「c:\midp-fcs\html」とします。
cd c:\midp-fcs\src\share\classes javadoc.exe -d c:\midp-fcs\html java.lang java.util javax.microedition.io javax.microedition.lcdui javax.microedition.midlet javax.microedition.rms
実際にはMIDP1.0正式版に付いてくるソースファイルにCLDCと共通の部分は含まれていないため、ここで製作するドキュメントには足りない部分が多数あります。
対応策としては、
・EarlyAccess版のドキュメントを見るというものがあります。
ここでは3番目の方法を紹介します。
CLDCのSDK(ソース含む)は「 http://java.sun.com/products/cldc/ 」からダウンロードできたと思います。 Sun Community Source Licensingと書かれていますが、特に気にしなくても大丈夫だと思います。
無事にソースを手に入れたら、新たなフォルダ(c:\midp-fcs\html)を作りそこにCLDCのソースをコピーします。今度はそこにMIDPのソースを上書きします。で、JavaDocです。
javadoc.exe -d c:\midp-fcs\html java.lang java.io java.util javax.microedition.io javax.microedition.lcdui javax.microedition.midlet javax.microedition.rms
ちなみにCLDCのダウンロードサイトにCLDCに関する日本語ドキュメントがあるので一度読まれると良いかもしれません。
「midp.exe」では標準で以下のような特徴があります。(2000/10/6)
・標準4階調モノクロ
・画面サイズ 96x100
・ヒープメモリ 300000バイト
・画像はPNGのみサポート
当然ながら、これらは将来発売される携帯電話に依存するもので、この状態専用のプログラムを組むと、エライコトになると思います。(^^;;
その他にパラメータを設定することで、
・2階調モノクロ化
・8Bitカラー化
なども可能です。
やり方は、「midp.exe」の実行前に、
set SCREEN_DEPTH=8
などとすればOKです。
SJIS対応、つまり日本語表示については、標準のmidp.exeではサポートされていないようです。
詳細が分かり次第追加したいと思います。
個人的に引っかかってしまった部分にこの「イメージの描画」があるのでご紹介(失敗談を語る^^;;)を。
イメージを描画するには、
Image image = Image.createImage("/image/test.png");
などとして、描画したいGraphicsオブジェクトで通常のJava同様「drawImage()」してやればいいのですが、このImage.createImage(Path)のPathでは、「/イメージパス」はOKでも「イメージパス」はNGです。(^^;;
つまり、イメージへのパスは「必ず最初にスラッシュ「/」を付けなければならない」ということです。
いやぁ、私、こんなことの為に1時間以上悩みました・・・。(^^;;;;
イメージの描画のサンプルソースを書いておきます。
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class ImageTest extends MIDlet implements CommandListener {
private Command exitCommand;
private ImageCanvas canvas;
public ImageTest(){
exitCommand = new Command("Exit",Command.SCREEN,2);
canvas = new ImageCanvas();
}
public void startApp(){
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
Display.getDisplay(this).setCurrent(canvas);
}
public void pauseApp(){}
public void destroyApp(boolean b){}
public void commandAction(Command c,Displayable s){
if(c==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}
class ImageCanvas extends Canvas {
private Image image = null;
public ImageCanvas(){
try{
image = Image.createImage("/test.png");//スラッシュ必須^^;;
}catch(Exception e){
System.out.println(e.toString());
}
}
public void paint(Graphics g){
g.drawImage(image,0,0, g.TOP | g.LEFT );
}
}
ちなみに、Graphics.drawImage(Image image,int x,int y,int anchor)の「int anchor」と言うのは、「Graphicsの x , y に image の anchor 部分がくる」というような感じで、上の場合、「イメージの左上( g.LEFT | g.TOP)」が座標(0,0)に来るという意味です。
これはとても便利で、今まで(通常のJava)は画面の真中にイメージや文字を表示したい場合は、画像の大きさやフォントの大きさを気にする必要がありましたが、MIDletでは、
Graphics.drawString("game over" , screen_width /2 ,screen_height /2 , Graphics.HCENTER | Graphics.BOTTOM );
としてやれば「game over」という「文字の中心(の下)」が「画面の中心」に来るように設定できます。
なお、「HCENTER:横の中心、VCENTER:縦の中心」ですが、文字(String)の場合はVCENTERが使えないのでご注意ください。
「screen_width,screen_height」はCanvasのgetWidth(),getHeight()で求めることができます。
「Javaと言えばアプレット」な人にはちょっと新鮮な機能、データの保存について。
MIDletでは「javax.microedition.rms.RecordStore」というローカルにデータを保存する機能があります。
始めてみる時にはちょっと分かりにくいと思うので紹介を。
MIDPでは通常のファイルに当たるものを「RecordStore」というもので扱います。
例えば、「RACEGAME」というRecordStoreオブジェクト(ファイル)を開くには、
RecordStore store = RecordStore.openRecordStore("RACEGAME",true);
などとします。
さらに、このRecordStoreオブジェクト内には「recordID」と呼ばれるインデックスで分別される複数のデータを保存できます。
つまり、構造的には、
RACEGAME(RecordStore)
|
+--record1:各データ1
|
+--record2:各データ2
|
+--record3:各データ3
|
+
ってな感じになります。
「midp.exe」で実行すると、PC上にRecordStoreのファイルとそのレコードが収められたファイルが作られます。
とても単純なサンプル>kinoさん
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
public class RecordTest extends MIDlet implements CommandListener {
private Command exitCommand;
private String name = "RecordTest";
public RecordTest(){
exitCommand = new Command("Exit",Command.SCREEN,2);
}
public void startApp(){
String[] data = {"test1","test2","test3","test4","test5"};
RecordStore recordStore = null;
// 書き込み(追加)
try{
recordStore = RecordStore.openRecordStore(name,true);
for(int i=0;i < data.length;i++){
byte[] b = data[i].getBytes();
recordStore.addRecord(b,0,b.length);
}
recordStore.closeRecordStore();
}catch(RecordStoreException e){
e.printStackTrace();
}
// 読み込み
String allData = "";
try{
recordStore = RecordStore.openRecordStore(name,false);
for(int i=0;i < recordStore.getNumRecords();i++){
byte[] b = recordStore.getRecord(i+1);
allData += new String(b);
}
recordStore.closeRecordStore();
}catch(RecordStoreException e){
e.printStackTrace();
}
TextBox box = new TextBox("records",allData,256,0);
box.addCommand(exitCommand);
box.setCommandListener(this);
(Display.getDisplay(this)).setCurrent(box);
}
public void pauseApp(){
}
public void destroyApp(boolean b){
// 削除
try{
RecordStore.deleteRecordStore(name);
}catch(RecordStoreException e){
e.printStackTrace();
}
}
public void commandAction(Command c,Displayable s){
if(c==exitCommand){
destroyApp(false);
notifyDestroyed();
}
}
}
destroyApp()の部分を無くせば実際にファイルとして保存されます。
・Commandのコンストラクタ
コンストラクタ最後の数値は優先度。優先度の高い順(1が最高)に右下、左下に表示される。ただし、2つ以上のコマンドが登録された場合は、片方に「MENU」というのが表示されて、そのMENUが選択されると別画面になり、画面に表示されなかったコマンドが並べられる。
・ペン入力
Canvasには「pointerPressed()」「pointerReleased()」「pointerDragged()」というメソッドがある。これはどうやらPalmのようなタッチパネルを想定してのものみたいだ。ちなみにmidp.exeでもマウス入力として試すことができる。
・日本語入力ができない
まぁ、仕方ないとも思いますが、将来的にどのように日本語を入力させるつもりなのかハッキリしてほしいですね。(^^;;
・Double,Floatが使えない
結構イタイ。いざ使えないとなると不便ですねぇ。(^^;;
・Mathが充実していない
Doubleが使えないのも原因の一つだと思いますが、あれではいったいなんのクラスなのか・・・・。
・セキュリティが甘い
と言うか、なんでもできますからねぇ。
・このまま使われるか分からない
一番の問題。(^^;;
こんなの動くかなぁ・・・・。(^^;;
一応迷路ですけど、ゴールは実装されていません。


MIDP final specification で実行できるようにしました。EAでは実行できませんのでご注意。
set SCREEN_DEPTH=8 c:\midp-fcs\bin\midp.exe -transient http://www.ngy1.1st.ne.jp/~takashi/MID/maze.jad
未だテストの上、かなり重いので注意!メモリを随分と使います!強制ガーベッジ有り!
| 戻る |