利用Java 编写手机应用程序
Motorola iDEN篇
王森
台湾交通大学科技管理研究所
moli.mt88g@nctu.edu.tw
█前言
本文内容的所有操作皆在Windows 200操作系统上经过测试。如果您在不同的平台上验证本文内容,例如Windows 98或是Windows Me,则我们无法保证会有相同的结果。
█简介
不知从什幺时候开始,我们突然感觉到周围的人各各拥有一只手机。利用手机与别人沟通成了我们生活的一部份。北欧某些先进国家的人民可以利用手机购买自动售货机所出售的商品;他们也可以在从事行动商务(m-commence) 交易时利用手机做为一种认证工具。在日本,行动电话的许多附加功能更是年轻人文化的一部分。即将来临的3G,无线宽频的美梦带给了人们对无线通讯未来的期待。
然后,有些厂商开始行销它们自己生产的PDA,好象没有一台PDA在手,就不像现代人似的。各式各样的PDA充斥市面,畅销的与不畅销的,让人眼花撩乱。这时产生了一个大问题--要我们同时携带手机和PDA是一件很麻烦的事情-就算它们都还算轻薄短小。如果可以把手机和PDA合而为一岂不是更方便吗? 于是听到消费者心声的厂商,开始有推出手机和PDA合而为一的产品,从NOKIA 9000、Motorola A6188(太极),到最近要推出的Ericsson R380、NOKIA 9210,都是手机与PDA结合的例子,虽然因为售价的关系,但是这些产品仍然是许多人梦寐以求的高阶产品。
尽管有了PDA与手机结合的产品出现,我们仍然觉得有所不足,我想大家一定发现了,就是应用程序的不足,虽然手机和PDA 结合了,可是这些产品上的PDA功能看起来似乎是死的。我们可以任意在PalmOS、Windows CE、EPOC等PDA上使用C/C++或是Java编写这些平台上的应用程序,但是却从未有过机会将我们写好的程序下载到这些手机上执行(即使有些手机的PDA也是使用EPOC,如Ericsson R380)。
相信厂商也听到我们这些喜欢到处写程序的工程师的心声了,所以从2000年年底开始,即将陆陆续续有许多支持Java的手机即将推出,当然,这些厂商也提供了在手机上开发程序的SDK,我们终于可以在手机上面写些小程序自娱了!这是以前等了很久的美梦。
手机平台的多样性与复杂性,和PDA比较起来可以说是有过之而无不及,于是大家就可以知道 - 哈!又是Java派上用场的时候了。我们都知道在浏览器上执行的Java程序叫做Applet,在PalmOS上执行的Java程序叫做Spotlet,然而在手机上执行的应用程序我们称做MIDlet,相信对大家来说都是一个陌生的名词,这也就是本篇文章所要介绍的主角。
支持Java的手机大厂目前已知有NOKIA (预计在2001年年初推出一款支持Java的手机NOKIA 9210)、Motorola(会先在支持integrated Digital enhanced network(iDen)网络的手机上支持Java,然后再推出支持Java的GSM手机,该公司的手机大致会在2002年前全部支持Java)以及NTT DoCoMo(将在明年第二季度左右推出支持Java的手机)。
虽然这些大公司都准备支持Java,不过在决定编写本文时,只有Motorola将其SDK开放于网站上供程序开发者下载测试,所以本文内容都是根据Motorola J2ME SDK所编写。又由于这些手机市面上无法取得,所以我们的程序都是在SDK内附的模拟器中执行,相信最后这些手机上市时,我们所编写的MIDlet应该会很容易并成功地在Motorola的手机上执行才对。
█如何取得Motorola J2ME SDK
我们要做的第一件事情当然还是要先取得SDK罗!
请直接到https://commerce.motorola.com/idenonline/ideveloper/下载Motorola J2ME SDK Drop 7。如果您不是iDEN® Developer的会员,请先在网络上注册(免费)。注册成功之后,Motorola会将密码寄到您的email信箱之中,然后使用该密码登入网页上的My Development Center。进入之后选择网页上头的TOOLS & RESOURCES以进入可下载的开发工具的网页,请选择Motorola J2ME SDK Components Developer Edition, Drop 7.0下方的下载超连结以下载SDK,整个SDK的大小约为3 MB左右。
请注意下载前的Download Page for Motorola J2ME™ SDK安装说明,里头会告诉你安装密码,请先行记下。稍后当您在您的电脑上安装Motorola J2ME SDK的时候,会询问您安装密码,所以请务必记下该密码。
█Motorola J2ME SDK的安装
安装需求
根据官方需求,安装Motorola J2ME SDK的基本配备为:
Pentium 100 MHz微处理器
64 MB RAM
Windows NT WorkStation 4.0配合Service Pack 3 / Win98
(本文是在Windows 2000 Professional中文版上测试)
约6 MB的硬盘空间
Java 2 SDK 1.2.2
(本文使用Java 2 SDK 1.3.0_01作测试)
安装Motorola J2ME SDK
要安装新版Motorola J2ME SDK之前,请先确认您已经将旧版的Motorola J2ME SDK完全删除。您可以由控制台里头的 「新增/删除程序」的功能删除旧版Motorola J2ME SDK。之后再将旧版Motorola J2ME SDK安装所在路径清除即可。
解开您从Motorola网站上下载的ZIP文件,您会看到一个名为Motorola_SDK.exe的文件,双击此文件即可开始安装动作。请注意,在安装时系统会要求您输入密码,请输入之前所纪录的安装密码即可。
█Motorola J2ME SDK目录结构
当您成功地安装Motorola J2ME SDK之后,其目录结构如下图:
█MIDlet程序结构
在手机上执行的程序我们统称MIDlet,其程序结构很简单,与大家熟悉的Applet结构有异曲同工之妙。
每一个MIDlet程序都必须继承自javax.microedition.midlet.MIDlet类别,并实做三个函式,它们分别是:
protected void startApp()
protected void pauseApp()
protected void destroyApp(Boolean unconditional)
而一个MIDlet程序的起始与结束之流程我们以下图来表示:
█编写并编译MIDlet
请先到您的Motorola J2ME SDK安装目录下的demo\midlets目录底下新建一个名为HelloMIDlet.java的文件,其内容为:
HelloMIDlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class HelloMIDlet extends MIDlet
{
HelloMIDlet()
{
}
protected void startApp() throws MIDletStateChangeException
{
}
protected void pauseApp()
{
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException
{
}
}
在demo\midlets目录之中您会看到一个名为compileAll.bat的批处理文件,前面有提到,这个批处理文件除了可以帮助您编译所有内附范例程序之外,还可以简化您自己所编写的MIDlet之编译流程。
请在命令列视窗输入: compileAll HelloMIDlet.java
如果成功编译,屏幕上输出的结果如下图所示:
从屏幕上的输出,您可以发现,要让MIDlet可以在手机上执行,大体上还是要经过两个动作(与Spotlet相似),分别是编译(compiling)以及预先审核(Preverifying)。
有关预先审核这个动作,笔者已经在RUN!PC 11月号的文章「利用Java 编写PalmOS应用程序基础篇」之中有向读者们提过,如果对这个方面有所疑问的朋友,请再将您的RUN!PC 11月号翻出来复习一下吧!
从这个简短的MIDlet制作流程里头,相信大家可以发现,比起纯粹用Sun的CLDC编写能在KVM上执行的Spotlet要简单上许多。原因是compileAll.bat这个批处理文件帮我们做掉大部分dirty work。
那幺,如果您写好的程序并非放在demo\midlets目录之中,是否就无法编译了? 从compileAll.bat里头,我们可以发现它帮我们完成上述两项工作的指令。如果我们写好的程序放在demo\midlets目录以外的地方,您可以执行下面的指令,您仍然可以成功地制作MIDlet:
(我们假设您的Motorola J2ME SDK安装在D:\MotoSDK目录之中,并将您自行编写的HelloMIDlet.java置于d:\jdk1.3.0_01\my目录之中。同时我们假设您在d:\jdk1.3.0_01\my目录底下执行下面指令。)
编译:
javac -O -bootclasspath d:\MotoSDK\lib HelloMIDlet.java
注意: -bootclasspath指向类函数库的所在位置。
预先审核:
d:\MotoSDK\bin\preverifier -classpath d:\MotoSDK\lib;. -d . HelloMIDlet
注意:
1 . -classpath指向类函数库的所在位置,也要指向我们所编写的MIDlet所在的位置。
2 .–d指向您希望预先编译类文件产生之后所放置的路径,如果写"."表示本目录,会覆盖掉原先未经过预先编译的类文件。如果您没有指定,则预设值为".\output"目录。
当然,如果您嫌自己手动操作很麻烦,您可以将compileAll.bat复制到其它目录之中,并更改其编译指令与预先审核指令之中和类函数库有关的相关设定即可。
提到compileAll.bat,顺便向各位读者说明一下,在前面有提到,compileAll.bat可以帮助您编译所有位于demo\midlets目录下的范例程序,您只要在命列列下直接输入: compileAll即可。compileAll.bat会自动当您编译的package有以下几项:
com.mot.j2me.midlets.bounce
com.mot.j2me.midlets.imagetests
com.mot.j2me.midlets.paddleball
com.mot.j2me.midlets.scribble
com.mot.j2me.midlets.tests
com.mot.j2me.midlets.tutorials
如果您希望compileAll.bat自动帮您编译其它package底下的程序,请您开启compileAll.bat,修改其COMPILECLASS环境变数的设定即可。
█修改并执行MIDlet
写好程序之后,大家最希望的事情当然就是让它在手机上执行,不过由于目前大家无法取得Motorola这些支持Java的手机,所以我们只能在Motorola J2ME SDK内附的模拟器上执行我们写好的MIDlet。相信手机正式推出时,应该可以顺利地在手机上执行。底下笔者将告诉您如何使用Motorola J2ME SDK内附的模拟器来测试您所编写的MIDlet。
在这之前,由于之前我们所编写的范例程序只是简单的MIDlet空壳,我们必须让它能够在模拟器上显示出一些信息才可以,因此请修改上一个程序范例,使它的内容如下:
HelloMIDlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class HelloMIDlet extends MIDlet
{
private Display firstDisplay ;
private Form firstForm ;
HelloMIDlet()
{
firstDisplay = Display.getDisplay(this) ;
firstForm = new Form("Hello MIDlet") ;
StringItem firstStrItem = new StringItem("Hello","MIDlet") ;
firstForm.append(firstStrItem) ;
}
protected void startApp() throws MIDletStateChangeException
{
firstDisplay.setCurrent(firstForm) ;
}
protected void pauseApp()
{
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException
{
}
}
请将此文件放置在\demo\midlets目录下。编译完成之后,请将目录切换到scripts子目录之中,您会在此目录里发现一些写好的批处理文件。请在该目录下执行这些批处理文件指令以启动模拟器。执行的指令与执行结果如下所示:
指令: runEmul HelloMIDlet
输出结果
指令: runMotoi1000 HelloMIDlet
输出结果
指令: runMotoiDEN HelloMIDlet
输出结果
指令: runStarTac HelloMIDlet
输出结果
指令: runMyDevice HelloMIDlet
输出结果
Error loading property file: C:/properties/mydevice.props (系统找不到指定的路径。)会出现错误信息是因为您没有指定属于是用者自订的手机外观的缘故,后面将会教您如何设定用户自订的手机外观。
如果我们将写好的程序放在demo\midlets目录以外的地方,您可以执行下面的指令,仍然可以成功地启动模拟器并执行MIDlet:
(我们假设您的Motorola J2ME SDK安装在D:\MotoSDK目录之中,并将您自行编写的HelloMIDlet.java置于d:\jdk1.3.0_01\my目录之中。同时我们假设您在d:\jdk1.3.0_01\my目录底下执行下面指令。)
执行一般模拟器
java -Djava.library.path=d:\MotoSDK\lib
-classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator
-classpath.;d:\MotoSDK\lib javax.microedition.midlet.AppManager HelloMIDlet
-JSA 1 1
请注意:
第一个-classpath设定,-classpath与路径名称之间有空格。
第二个-classpath设定,-classpath与路径名称之间没有空格。
执行模拟器并套用i1000手机外观
java -Djava.library.path=d:\MotoSDK\lib
-classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator
-classpath.;d:\MotoSDK\lib
-deviceFile resources\Motorolai1000.props
javax.microedition.midlet.AppManager
HelloMIDlet
-JSA 1 1
请注意:
第一个-classpath设定,-classpath与路径名称之间有空格。
第二个-classpath设定,-classpath与路径名称之间没有空格。
执行模拟器并套用iDEN手机外观
java -Djava.library.path=d:\MotoSDK\lib
-classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator
-classpath.;d:\MotoSDK\lib
-deviceFile resources\MotorolaiDENPlatform.props
javax.microedition.midlet.AppManager
HelloMIDlet
-JSA 1 1
请注意:
第一个-classpath设定,-classpath与路径名称之间有空格。
第二个-classpath设定,-classpath与路径名称之间没有空格。
执行模拟器并套用StarTac手机外观
java -Djava.library.path=d:\MotoSDK\lib
-classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator
-classpath.;d:\MotoSDK\lib
-deviceFile resources\StarTac.props
javax.microedition.midlet.AppManager
HelloMIDlet
-JSA 1 1
请注意:
第一个-classpath设定,-classpath与路径名称之间有空格。
第二个-classpath设定,-classpath与路径名称之间没有空格。
执行模拟器并套用用户自订手机外观
java -Djava.library.path=d:\MotoSDK\lib
-classpath d:\MotoSDK\bin\Emulator.jar;d:\MotoSDK\bin\ConfigTool.jar com.mot.tools.j2me.emulator.Emulator
-classpath.;d:\MotoSDK\lib
-deviceFile <您的props文件所在的绝对路径>javax.microedition.midlet.AppManager
HelloMIDlet
-JSA 1 1
请注意:
第一个-classpath设定,-classpath与路径名称之间有空格。
第二个-classpath设定,-classpath与路径名称之间没有空格。
如果您将您的props文件放在d:\MotoSDK\bin的resources目录之下,则上述指令只要改成:-deviceFile resources\<您的props文件名>
注意,当您您直接使用上述指令启动模拟器,如果出现底下错误信息:
Error loading property file: resources/defaultdevice.props (系统找不到指定的路径。)
这是因为您没有将d:\MotoSDK\bin目录下的resources子目录复制到d:\JDK1.3.0_01\my目录之下的缘故。
█对MIDlet进行调试
编写PalmOS上的Spotlet时,我们可以利用System.out.println()函式帮我们印出一些讯息以帮助调试,那幺在手机上的MIDlet呢? 原则上,我们还是可以利用System.out.println()函式做一些输出。当模拟器执行时,就会在命令列上输出一些讯息。
另外,在PalmOS上,有KVMutil.prc可以帮助我们纪录程序所输出的讯息。那手机上呢? 因为没有实际的机器可以测试,因此这个问题到现在还不得而知,相信Motorola到时候会有完善的解决方案吧!
在Motorola J2ME SDK内附的说明文件之中,概略地提到了调试的问题,里头提到,往后如果我们要进行机上调试(on-device debugging)的话,必须要满足几个条件:
机器本身要具备调试相关功能,并与KDWP(Kvm Debug Wire Protocol)兼容。因为调试时,调试工具需要利用KDWP和机器上交谈以取得调试信息。
制造厂商本身要提供下载MIDlet到手机上以进行调试的方法。
提供对MIDlet调试的工具,必须支持手机在利用KDWP调试时所使用的传输接口(例如串行口或UDP)。
嗯,看起来能够进行调试,MIDlet程序的编写应该是很方便的事情了。
█Motorola J2ME SDK对中文的支持
相信看过RUN!PC 11月号的文章「利用Java 编写PalmOS应用程序基础篇」的读者,在编写PalmOS上的Spotlet时一定会遇到中文无法正常显示的问题。中文的问题分成两个部分,一个是在用户接口上的中文问题,一个是在命令列输出(利用System.out.println()函式所做的输出)上的中文问题,请大家做个小实验,将前面我们所编写的程序改如下:
HelloMIDlet.java
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class HelloMIDlet extends MIDlet
{
private Display firstDisplay ;
private Form firstForm ;
HelloMIDlet()
{
firstDisplay = Display.getDisplay(this) ;
firstForm = new Form("哈罗!MIDlet") ;
StringItem firstStrItem = new StringItem("哈罗","米德列特") ;
firstForm.append(firstStrItem) ;
System.out.println("MIDlet启动") ;
}
protected void startApp() throws MIDletStateChangeException
{
firstDisplay.setCurrent(firstForm) ;
}
protected void pauseApp()
{
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException
{
}
}
将本MIDlet编译并经过预身审核之后,我们开启模拟器来执行此MIDlet,底下为执行结果:
用户接口输出:
命令列输出
我们从结果发现,预设的编译指令会让用户接口正常输出中文,而命令列无法输出正确的中文。
我们从结果发现,预设的编译指令会让用户接口正常输出中文,而命令列无法输出正确的中文。
接着请将compileAll.bat之中原本的指令
javac -O -bootclasspath ..\..\lib %COMPILECLASS%
修改为
javac –encoding ISO8859_1 -O -bootclasspath ..\..\lib %COMPILECLASS%
之后,重新编译此MIDlet执行结果:
用户接口输出:
命令列输出
我们从结果发现,预设的编译指令会让用户接口无法正常输出中文,而命令列却可以输出正确的中文。
这个结果与PalmOS上所做的中文测试结果有所不同。
当您编写Spotlet时,如果您使用javac 。。。指令时,您会发现模拟器上的用户接口输出是乱码,可是命令列上的输出却可以正常输出中文。但是如果您使用的是javac -encoding ISO8859_1 。。。指令,则CLDC内附模拟器上的用户接口输出或是命令列上的输出全部都变成乱码,无法正常输出中文(这个部分是因为CLDC内附模拟器实做的问题,造成与实际机器的结果有差异)。
总之,如果之前您所编写的Spotlet无法在装有中文系统的实际机器或POSE上正常输出中文,请您也如法炮制,在编译指令中加入-encoding ISO8859_1,就可以在实际机器或POSE上看到正常的中文字了。
会产生此问题的主因,主要是因为编译好的Java类文件(byte code)之中,所有的文字编码都采用UTF8。举例来说,当您在程序码里用到"启动"这两个中文字时,
"起"这个字的Big5编码为B1D2。
"动"这个字的Big5编码为B0CA。
我们会使用javac xxxx.java来编译原始码以产生类文件。其实这行指令,在繁体中文的Windows环境底下,相当于javac -encoding "Big5" xxxx.java。也就是说,当编译器读取到Big5编码范围的中文字时,会自动将此Big5码经过「Big5è Unicode 对照表」将Big5转为Unicode,也就是说,经过查表之后,
“起”这个字的Unicode编码为555F。
“动”这个字的Unicode编码为5272。
然后再利用UTF8编码将此Unicode转为UTF8,储存在类文件之中,因此,如果您用UltraEdit之类的文字编辑器查看类文件时,您会看到,
"起"这个字的UTF8编码为E5959F。
"动"这个字的UTF8编码为E58B95。
接着,当我们在程序执行时如果要将中文输出,则JVM会负责读进UTF8码,然后将其转回Unicode,最后依据您所使用的系统环境预设的编码转回Big5,再输出至屏幕上。
可是经过测试结果,KVM似乎只有做到把UTF8读进来,转换回Unicode之后就直接输出了。少了转回Big5的步骤,因此,操作系统把Unicode当作Big5来处理,自然就找不到该码所对应的中文字了,也因此输出的是一堆 ????? 的符号。这也是我们在PalmOS上即使装了中文系统,也无法正常显示中文的缘故。
OK,既然知道KVM只帮我们做了一半的工作,那事情就好办了,我们只要让UTF8转回之后,仍然保有Big5的编码方式即可,于是我们使用指令javac -encoding ISO8859_1 xxxx.java,请编译器不要将程序码中中文Big5编码的两个byte视为一体(因为视为一体就会引发查询Big5 è Unicode对照表的工作),只要将中文当作是普通的西欧字母字集即可,因此,当我们使用了上述指令,您会发现类文件之中的中文变成,
"起"这个字的UTF8编码为C2B1 C392。
"动"这个字的UTF8编码为C2B0 C38A。
大家可以发现编译器把B1、D2、B0、CA个别当作一个码来处理。于是,当KVM读到此编码时,就会将他们转回B1D2以及B0CA,然后KVM直接输出,就可以正常地使用中文了。
最后总结整个问题,就笔者的推断,CLDC内附的模拟器再没有使用javac –encoding ISO8859_1 xxxx.java指令之前,会在用户接口使命令列输出乱码,这才是正常的结果, 而Motorola J2ME SDK内附模拟器的用户接口中文之所以没问题,很可能只是因为模拟器操作的差异。因此根据KVM的输出结果来看,很可能在实际的手机上,我们都必须加上-encoding ISO8859_1选项才能正确输出中文吧!
在此特别感谢静宜大学资管系的唐恺隆(kailung.tang@msa.hinet.net)同学。因为笔者于他经过热烈的讨论之后,我们才能对J2ME的中文问题有更深入的认识
█支持Motorola J2ME SDK的开发工具
在编写本文的时候,支持MIDlet开发的集成开发环境(IDE)只有Motorola J2ME SDK附带文件之中所提到的CodeWarrior而已。相信其它厂商,如Borland,应该也会很快地利用其产品JBuilder的OpenTools API来支持MIDlet的开发才对,更何况Borland JBuilder目前已经有Spotlet的解决方案了。
因为笔者无法拿到CodeWarrior作测试,所以无法在此提供大家相关信息,相信如果有机会的话,会另外以专文向大家介绍如何利用CodeWarrior编写MIDlet。
Motorola J2ME SDK附带文件在附录的部分有对利用CodeWarrior开发MIDlet做简单的介绍,相信对初学者来说,已经相当足够了。
█Motorola J2ME SDK内含的辅助开发工具
在Motorola J2ME SDK之中内含三项辅助开发工具,可以便利我们的程序开发工作,它们分别是:
J2ME模拟器(J2ME Emulator)
让您可以在您的PC上模拟Motorola将来会支持J2ME的手机装置。如此一来就可以在PC上直接测试写好的程序。
Bytecode验证器(Bytecode Verifier)
此验证器用来验证类文件(classfile)之中的bytecode不会对存储器做非法的存取。并确认载入虚拟机器的类文件所做的所有动作皆符合Java虚拟机器规格(Java Virtual Machine Specification)。
配置编辑器(Configuration Editor)
让您能够建立或修改device profile。
在Motorola J2ME SDK内附的文件之中对这三个工具有详细的说明,笔者在此就不再赘述了。
█总结
呼!好累人,终于到了该做总结的时候了! 大家以为MIDlet就这样结束了吗?不! MIDlet还有许多好玩的玩意儿呢! 我们将在本系列之后的文章中为大家更深入探讨MIDlet。咱们下次见。
█附录:范例程序
Motorola J2ME SDK之中内附许多有趣的范例,它们位于demo/midlets/目录底下。有兴趣继续精进的读者可以由这些范例学到更多有关MIDlet的深入技巧,由于这些范例的执行画面过大,所以在本文之中就将他们省略,请读者们自行参考说明文件。
这些范例程序有:
Bounce
com.mot.j2me.midlets.bounce.Bounce
PaddleBall
com.mot.j2me.midlets.paddleball.PaddleBall
Scribble
com.mot.j2me.midlets.scribble.Scribble
FontDemo
com.mot.j2me.midlets.tutorials.FontDemo
GraphicsDemo
com.mot.j2me.midlets.tutorials.GraphicsDemo
RecordStoreDemo
com.mot.j2me.midlets.tutorials.RecordStoreDemo
UDP Tutorial Application
com.mot.j2me.midlets.tutorials.UDPReceive
AlertTest
com.mot.j2me.midlets.tests.AlertTest
ChoiceGroupTest
com.mot.j2me.midlets.tests.ChoiceGroupTest
DateFieldTest
com.mot.j2me.midlets.tests.DateFieldTest
FormTest
com.mot.j2me.midlets.tests.FormTest
GaugeTest
com.mot.j2me.midlets.tests.GaugeTest
KeyEventsTest
com.mot.j2me.midlets.tests.KeyEventsTest
TextBoxTest
com.mot.j2me.midlets.tests.TextBoxTest
TextFieldTest
com.mot.j2me.midlets.tests.TextFieldTest
TickerTest
com.mot.j2me.midlets.tests.TickerTest
█网络资源
◎网站
名称 URL
Motorola官方网站 http://www.motorola.com/java/
Metrowerks(CodeWarrior) http://www.Metrowerks.com