Professional Documents
Culture Documents
Mobile Programming
Mobile Programming
II.
14
Lch s.................................................................................................................14 L do chn J2ME...............................................................................................14 Kin trc ca J2ME...........................................................................................14 Gii thiu MIDP ................................................................................................17 Mi trng pht trin J2ME ............................................................................23
III.
IV.
51
Cc hm API mc thp..................................................................................51 Lp Canvas.........................................................................................................51 Lp Graphics .....................................................................................................61 Cc hm API dng lp trnh Game ............................................................78
V.
X l s kin
79
V.1. i tng Command .........................................................................................79 V.2. i tng Item ...................................................................................................80 V.3. V d....................................................................................................................80
VI.
VII.
135
VII.1.Nhng protocol c h tr trong GCF .......................................................136 VII.2.H tr giao thc HTTP trong MIDP.............................................................142 VII.3.Accessing a Java servlet ..................................................................................152
VIII.
Ph lc
VIII.1. VIII.2. VIII.3.
157
Tng s class v interface trong CLDC .................................................157 Thng tin ca cc dng in thoi thng dng.....................................158 Tham kho: ..............................................................................................178 1
I.
I.1.
I.1.1.
Tin s Martin Cooper, cu tng gim c n v h thng ca Motorola, c coi l cha ca thit b lin lc di ng cm tay v cng l ngi u tin thc hin mt cuc gi thng qua cng c ny. tng lin lc di ng c b phn nghin cu AT&T thuc Trung tm Bell Labs (M) a ra nm 1947. Nhng n cui nhng nm 60 v u thp k 70 ca th k trc, Motorola v Bell Labs mi thc s tr thnh 2 i th lao vo cuc ua trong vic tch hp cng ngh ny vo cc thit b c nhn di ng. K s in Cooper tng c 4 nm phc v trong hi qun trc khi chuyn v lm vic cho mt cng ty vin thng nh. Nm 1954, ng c Motorola tuyn dng v tham gia pht trin cc sn phm di ng, ng ch nht l cng c lin lc radio di ng u tin dnh cho cnh st Chicago nm 1967. Nm 1973, ng thit lp mt trm thu pht ti New York ng thi tung ra mu u tin ca ci gi l in thoi di ng (cellphone): my Motorola Dyna-Tac. Sau nhng cuc th nghim ban u ti Washington, Cooper v Motorola quyt nh a cng ngh mi ti New York qung b vi cng chng. Motorola Dyna-Tac - chic in thoi di ng u tin: Kch thc (cm): 22,86 x 12,7 x 4,44 Trng lng: 1,13kg Mn hnh: khng c S bo mch in: 30 Thi lng thoi: 35 pht Thi lng pin: 10 ting Tnh nng: Ni, nghe, quay s. Ngy 3/4/1973, ng trn mt ph gn khch sn Manhattan Hilton, Cooper quyt nh th thc hin mt cuc gi ring trc khi i ln gc tham d mt cuc hp bo gii thiu thit b. C in thoi y c ng gi ti chnh i th cnh tranh ca mnh: Joel Engel, Gim c Trung tm th nghim Bell Labs. Tht tuyt vi, hn gch bit ni nng hn 1kg ca Cooper hot ng rt tt, kt ni ng vi trm thu pht t trn nc ta thp Burlington Consolidated (nay l ta nh Alliance Capital Building) New York, ng thi lin lc c vi c ng dy c nh. Nhng ngi qua ng t ra rt ngc nhin khi thy mt ngi n ng bm bm mt cng c g , p st vo tai v ri say sa ni chuyn. Ni v tng lai ca ngnh di ng, tin s Cooper, nm nay ngoi 70 tui, cho rng th gii vin thng thc ra vn cn rt non tr v mi ang bt u bng n. ng lc cho qu trnh bng n y trc ht l quan nim kinh doanh mi, trong ch trng vo ngi tiu 2
dng. Quan trng hn na l mt nn hot ng m, trong c nhng cng ngh mi vi kh nng tng cng khai thc gii tn. Bn cnh , nh pht minh vin thng cho rng, cn c chnh sch u tin cho nhng i tng bit khai thc tt nht gii tn sng hin c. Nhng thay i s khng din ra qu nhanh, nhng trong 10 nm ti, s l nhng chuyn bin c tnh c bn, Cooper nhn nh. Li khuyn ca ti v cng ngh lin lc di ng trong tng lai, nht l i vi cc th trng ang pht trin, l hy t t, chm nhng hiu qu. Theo ng, cn thn trng trong vic phn b gii tn i vi mi ng dng c th. V khi phn b, d l cho th h 3G hay 4G, cn tin hnh mt cch hp l ty thc t ca mi th trng. i vi cc nc ang pht trin, Cooper cho rng khng nn vi cun theo s cm d ca xu th nhy sang 3G, cho ti khi no thy r c nhng ch li c th cho mi ngnh kinh t v mi quc gia.
I.1.2.
Lch s cc thit b
TD gi y ang hng ti mc tiu "siu mng v siu nh". Nhng bn c tin khng, ban u, "c t" ca n nng n 10 y! 1. Motorola DynaTAC 8000X (1982)
Nm 1973, Motorola gii thiu dng "al" di ng u tin ca th gii di 27 cm, nng 1kg, gi 3.995 USD. Tuy nhin, phi n nm 1983, thit b ny mi bt u xut hin trn th trng nm. Motorola DynaTAC 8000X cho php m thoi mt gi, b nh c th lu .. 30 s. Trng b ngoi thit b ny khng p mt nhng li cho php bn va i va ni chuyn bt k u.
Mi nhn Nokia Mobira Senator ging... hp bom hn in thoi di ng, nhng thit b hnh hp to s ny l in thoi u tin ca Nokia. c gii thiu nm 1982, Nokia Mobira Senator c thit k s dng trong xe t. N nng khong... 10 kg. 3. PDA Simon Personal Communicator (1993)
in thoi c tnh nng PDA by gi khng cn mi. Nhng nm 1993 y l mt tng mi l. Simon Personal Communicator l in thoi u tin c tnh nng ca lin minh IBM v BellSouth. N l in thoi kim my tnh, s a ch, my fax v e-mail... Gi 900 USD.
Trc khi Motorola Star TAC c gii thiu nm 1996, cc tnh nng in thoi di ng c ch trng nhiu hn thi trang. Nhng thit b nh b c th gp ny cho thy rng phong cch l cc k quan trng. Motorola StarTAC 3.1 ounce l nh nht trong thi im v n nay n vn nh v nh hn nhiu "d" khc. 5. Nokia 6160 (1998) v Nokia 8260 (2000)
. Vo nhng nm 1990, cc in thoi hnh thi ko ca Nokia xut hin hng lot. Nhng Nokia 6160 v Nokia 8260 gy c s ch ca nhiu ngi. Nokia 6160 c mn hnh en trng, ng-ten ngoi, thn 5,2 inch, nng 6 ounce. Nokia 8260 ra mt nm 2000 n tng hn khi c t im chic o mu, di 4 inch, nng ch 3,4 ounce.
Nu bn l mt trong nhng ngi hm m in thoi Treo s dng h iu hnh Palm th c th cm n Kyocera. D thng minh QCP6035 ca cng ty ny thng lnh th trng bn l nm 2001. Vi gi 400 USD v 500 USD, y l in thoi dng phn mm Palm u tin c phn phi rng ri. Sn phm c 8 MB b nh, mn hnh trng en. 7. PDA n in thoi: Handspring Treo 180 (2001)
Tr li khi Palm v Handspring cn l i th. Handspring khuy ng th trng vi sn phm Treo 180 gm hai phin bn: mt vi bn pm QWERTY v mt Treo 180g vi thit b nhp liu Graffiti. Nh Kyocera QCP6035, n c mn hnh en trng nhng c 16MB b nh.
Mobile Programming (Private Version) 8. Tin phong v thit k xoay: Danger Hiptop (2002)
T-Mobile Sidekick tng c mnh danh l sn phm ca nm 2003. Mc d cc kh nng m thoi ca n xong, nhng l mt trong nhng thit b u tin cung cp tnh nng duyt web, truy cp email v nhn tin. Hn th na, n l ngi tin phong v thit k xoay trn. 9. in thoi cch tn: BlackBerry 5810 (2002)
BlackBerry 5810 c bit n nhng mt thit b in hnh v cc kh nng x l d liu. y l sn phm u tin cung cp cc tnh nng voice, GSM.
Mobile Programming (Private Version) 10. t ph vi tnh nng chp nh: Sanyo SCP-5300 (2002)
Sanyo SCP-5300 PCS l "d" u tin c tnh nng chp nh c Sanyo v Sprint gii thiu nm 2002. phn gii cao nht n c th chp c cc nh VGA (640 x 480), nhng n nay, tt nhin, n khng th sanh vi cc in thoi kim my nh 5 megapixel. 11. in thoi kim my chi game Nokia N-Gage (2003)
Dng my N-Gage to c nhiu d lun khi xut hin trn th trng nm 2003, nhng tht khng may, li l sn phm bt li. S kt hp in thoi di ng/thit b chi game c k vng s quyn r c game th t b my chi game cm tay ca h. Nhng thay vo , n gy phn cm bi thit k hnh bn nguyt k quc.
Mobile Programming (Private Version) 12. Siu mng: Motorola Razr v3 (2004)
in thoi di ng ngy cng mng v phong cch hn, nhng Motorola Razr v3 l sn phm u tin gy n tng v thit k thi thng mng v nh vo 2004. Ba nm sau "d" ny vn c nh gi l mt trong nhng in thoi ph bin nht trn th trng. 13. in thoi nghe nhc Motorola Rokr (2005)
Motorola Rokr in thoi di ng kim my nghe nhc u tin s dng phn mm nghe nhc ca Apple. Vi thit b ny, ngi dng c th thng thc cc bi ht, bn nhc t dch v iTunes.
Mobile Programming (Private Version) 14. Phong cch: BlackBerry Pearl (2006)
Thit k mng, bn phm SureType, tnh nng chp nh, nghe nhc, xem video, h tr dch v e-mail n tng v nhiu kh nng a phng tin khc, BlackBerry Pearl tr thnh vin ngc qu ca khng t ngi. 15. Cch tn vi Apple iPhone (2007)
Sau nhng thng ch i, Apple khng nh thng 6 l thi im quan trng iPhone s xut hin trn th trng. y l thit k cch tn vi mn hnh cm ng cm ng a im s mang li mt th gii sinh ng vi e-mail bng ging ni, bn phm "mm" dng Qwerty c th on t, trnh duyt web Safari, tch hp camera2-megapixel. iPhone l thit b gy t m nht trong gii chi in thoi di ng, dng h iu hnh Mac OS X. Gi bn: 500 USD cho mu 4 GB, 600 USD cho mu 8 GB.
10
I.2.
a. GMS: H thng thng tin di ng ton cu H thng thng tin di ng ton cu (ting Anh: Global System for Mobile Communications; ting Php: Groupe Spcial Mobile; vit tt: GSM) l mt cng ngh dng cho mng thng tin di ng. Dch v GSM c s dng bi hn 2 t ngi trn 212 quc gia v vng lnh th. Cc mng thng tin di ng GSM cho php c th roaming vi nhau do nhng my in thoi di ng GSM ca cc mng GSM khc nhau c th s dng c nhiu ni trn th gii. GSM l chun ph bin nht cho in thoi di ng (TD) trn th gii. Kh nng ph sng rng khp ni ca chun GSM lm cho n tr nn ph bin trn th gii, cho php ngi s dng c th s dng TD ca h nhiu vng trn th gii. GSM khc vi cc chun tin thn ca n v c tn hiu v tc , cht lng cuc gi. N c xem nh l mt h thng TD th h th hai (second generation, 2G). GSM l mt chun m, hin ti n c pht trin bi 3rd Generation Partnership Project (3GPP) ng v pha quan im khch hng, li th chnh ca GSM l cht lng cuc gi tt hn, gi thnh thp v dch v tin nhn. Thun li i vi nh iu hnh mng l kh nng trin khai thit b t nhiu ngi cung ng. GSM cho php nh iu hnh mng c th sn sng dch v khp ni, v th ngi s dng c th s dng in thoi ca h khp ni trn th gii. Giao din radio GSM l mng in thoi di ng thit k gm nhiu t bo do cc my in thoi di ng kt ni vi mng bng cch tm kim cc cell gn n nht. Cc mng di ng GSM hot ng trn 4 bng tn. Hu ht th hot ng bng 900 Mhz v 1800 Mhz. Vi nc Chu M th s dng bng 850 Mhz v 1900 Mhz do bng 900 Mhz v 1800 Mhz ni ny b s dng trc. Cc mng s dng bng tn 900 Mhz th ng uplink s dng tn s trong di 890-915 MHz v ng downlink s dng tn s trong di 935-960 MHz. V chia cc bng tn ny thnh 124 knh vi rng bng thng 25 Mhz, mi knh cch nhau 1 khong 200 Khz. S dng cng ngh phn chia theo thi gian TDM (time division multiplexing) chia ra 8 knh full rate hay 16 knh haft rate. C 8 khe thi gian gp li gi l 1mt khung TDMA. Tc truyn d liu ca mt knh l 270.833 kbit/s v khong thi gian ca mt khung l 4.615 m. Cng sut pht ca my in thoi c gii hn ti a l 2 watt i vi bng GSM 850/900 Mhz v ti a l 1 watt i vi bng GSM 1800/1900 Mhz. Mng GSM s dng 2 kiu m ho m thanh nn tn hiu m thanh 3,1 Khz l m ho 6 v 13 kbps gi l full rate (13 kbps) v haft rate (6 kbps). nn h s dng h thng c tn l linear predictive coding (LPC).Vo nm 1997 th h ci tin thm cho mng GSM l b m GSM-EFR s dng full rate 12,2 kbps. C tt c bn kch thc cell site trong mng GSM l macro, micro, pico v umbrella. Vng ph sng ca mi cell ph thuc nhiu vo mi trng. Macro cell c lp trn ct cao hoc trn cc to nh cao tng, micro cell li c lp cc khu thnh th, khu dn c, pico cell
11
th tm ph sng ch khong vi chc mt tr li n thng c lp tip sng trong nh. Umbrella lp b sung vo cc vng b che khut hay cc vng trng gia cc cell. Bn knh ph sng ca mt cell tu thuc vo cao ca anten, li anten thng th n c th t vi trm mt ti vi chc km. Trong thc t th kh nng ph sng xa nht ca mt trm GSM l 32 km (22 dm). Mt s khu vc trong nh m cc anten ngoi tri khng th ph sng ti nh nh ga, sn bay, siu th... th ngi ta s dng cc trm pico chuyn tip sng t cc anten ngoi tri vo. b. GPRS (General Packet Radio Service) l dch v v tuyn gi tng hp c pht trin trn nn tng cng ngh thng tin di ng ton cu (GSM) s dng a truy nhp phn chia theo thi gian (TDMA). Cng ngh GPRS hay cn bit n vi mng di ng th h 2.5G, p dng nguyn l gi v tuyn truyn s liu ca ngi s dng mt cch c hiu qu gia my in thoi di ng ti cc mng truyn s liu. c. EDGE (Enhanced Data Rates for GSM Evolution), i khi cn gi l EGPRS, l mt cng ngh di ng c nng cp t GPRS cho php truyn d liu vi tc c th ln n 384 kbit/s cho ngi dng c nh hoc di chuyn chm v 144kbit/s cho ngi dng di chuyn tc cao. Trn ng tin n 3G, EDGE c bit n nh mt cng ngh 2.75G. Thc t bn cnh iu ch GMSK, EDGE dng phng thc iu ch 8-PSK tng tc d liu truyn. Chnh v th, trin khai EDGE, cc nh cung cp mng phi thay i trm pht sng BTS cng nh l thit b di ng so vi mng GPRS. d. CDMA (Code Division Multiple Access), ting Vit gi l phng thc a truy cp phn chia theo m, l mt k thut a truy cp vo knh truyn vt l s dng k thut phn chia theo m (code). Trong k thut CDMA, tn hiu ca mi ngi dng (user) s c dn tri (spreading) bng 1 m xc nh trc giao (hoc gi trc giao) vi nhau. Tn hiu truyn s l tn hiu chng chp ca nhiu ngi dng khc nhau theo thi gian v trn cng 1 bng tn s. K thut CDMA hin ang c s dng rng ri trong cc h thng in thoi di ng: IS95A/B, CDMA2000, WCDMA(UMTS)... e. CDMA2000 l mt h chun thng tin di ng s dng cng ngh CDMA c chun ha bi 3GPP2. CDMA2000 bao gm 3 chun chnh: CDMA2000 1xRTT, CDMA2000 EV-DO, CDMA2000 EV-DV. CDMA2000 hot ng trong di tn s 450 MHz, 700 MHz, 800 MHz, 900 MHz, 1700 MHz, 1800 MHz, 1900 MHz, v 2100 MHz. CDMA2000 l cng ngh 3G tip ni ca cng ngh 2G CdmaOne (hay IS-95) v c xem nh l mt i th cnh tranh vi cng ngh 3G/UMTS. Tuy nhin, CDMA2000 1xRRT thng c nhc n nh l mt cng ngh 2.5G (tng ng vi GPRS). f. CDMA2000 EV-DO (Evolution-Data Optimized) l mt chun thng tin di ng thuc h CDMA2000, kt hp gia k thut CDMA v TDMA cung cp dch v s liu tc cao. CDMA2000 EV-DO c QualComm xut vo 3/2000 v c chun ha bi 3GPP2. c im ni bt ca CDMA2000 EV-DO:
12
- EV-DO h tr tc s liu hng xung 2,4576 Mbps trn bng thng 1,25 MHz v tc s liu hng ln 153,6 Kbps. - Trm gc linh hot d dng pht cng sut ln. - H tr s iu ch cp cao km vi kh nng thc hin nhiu phng php sa li. - K thut chuyn mch l chuyn mch gi ghp knh theo thi gian. g. Time Division Multiple Access (TDMA), ting Vit gi l phng thc a truy cp phn chia theo thi gian, l mt k thut a truy cp vo knh truyn vt l s dng k thut phn chia theo thi gian.
13
14
a) Gii thiu cc thnh phn trong nn tng J2ME: nh ngha v Configuration (Cu hnh): l c t nh ngha mt mi trng phn mm cho mt dng cc thit b c phn loi bi tp hp cc c tnh, v d nh: Kiu v s lng b nh Kiu v tc b vi x l Kiu mng kt ni Do y l c t nn cc nh sn xut thit b nh Samsung, Nokia bt buc phi thc thi y cc c t do Sun qui nh cc lp trnh vin c th da vo mi trng lp trnh nht qun v thng qua s nht qun ny, cc ng dng c to ra c th mang tnh c lp thit b cao nht c th. V d nh mt lp trnh vin vit chng trnh game cho in thoi Samsung th c th sa i chng trnh ca mnh mt cch ti thiu nht c th chy trn in thai Nokia.. Hin nay Sun a ra 2 dng Configuration: CLDC (Connected Limited Device Configuration-Cu hnh thit b kt ni gii hn): c thit k nhm vo th trng cc thit b cp thp (low-end), cc thit b ny thng thng l my in thai di ng v PDA vi khong 512 KB b nh. V ti nguyn b nh hn ch nn CLDC c gn vi Java khng dy (Java Wireless ), dng nh cho php ngi s dng mua v ti v cc ng dng Java, v d nh l Midlet. CDC- Connected Device Configuration (Cu hnh thit b kt ni): CDC c a ra nhm n cc thit b c tnh nng mnh hn dng thit b thuc CLDC nhng vn yu hn cc h thng my bn s dng J2SE. Nhng thit b ny c nhiu b nh hn (thng thng l trn 2Mb) v c b x l mnh hn. Cc sn phm ny c th k n nh cc my PDA cp cao, in thoi web, cc thit b gia dng trong gia nh C 2 dng Cu hnh k trn u cha my o Java (Java Virtual Machine) v tp hp cc lp (class) Java c bn cung cp mt mi trng cho cc ng dng J2ME. Tuy nhin, bn ch rng i vi cc thit b cp thp, do hn ch v ti nguyn nh b nh v b x l nn khng th yu cu my o h tr tt c cc tnh nng nh vi my o ca 15
J2SE, v d, cc thit b thuc CLDC khng c phn cng yu cu cc php tnh ton du phy ng, nn my o thuc CLDC khng c yu cu h tr kiu float v double.
Bng di l s so snh cc thng s k thut ca CDC v CLDC CLDC CDC Ram >=32K, <=512K >=256K Rom >=128k, <=512k >=512k Ngun Nng C GiI Hn (ngun pin) Khng gii hn Lng Network Chm Nhanh nh ngha veef Profile: Profile m rng Configuration bng cch thm vo cc class b tr cc tnh nng cho tng thit b chuyn bit. C 2 Configuration u c nhng profile lin quan v t nhng profile ny c th dng cc class ln nhau. n y ta c th nhn thy do mi profile nh ngha mt tp hp cc class khc nhau, nn thng ta khng th chuyn mt ng dng Java vit cho mt profile ny v chy trn mt my h tr mt profile khc. Cng vi l do , bn khng th ly mt ng dng vit trn J2SE hay J2EE v chy trn cc my h tr J2ME. Sau y l cc profile tiu biu: Mobile Information Device Profile (MIDP): profile ny s b sung cc tnh nng nh h tr kt ni, cc thnh phn h tr giao din ngi dng vo CLDC. Profile ny c thit k ch yu nhm vo in thai di ng vi c tnh l mn hnh hin th hn ch, dung lng cha c hn. Do MIDP s cung cp mt giao din ngi dng n gin v cc tnh nng mng n gin da trn HTTP. C th ni MIDP l profile ni ting nht bi v n l kin thc c bn cho lp trnh Java trn cc my di ng (Wireless Java) PDA Profile: tng t MIDP, nhng vi th trng l cc my PDA vi mn hnh v b nh ln hn Foundation Profile: cho php m rng cc tnh nng ca CDC vi phn ln cc th 16
vin ca b Core Java2 1.3 Ngoi ra cn c Personal Basis Profile, Personal Profile, RMI Profile, Game Profile.
Cc lp v kiu d liu: Phn ln cc lp m cc lp trnh vin Java quen thuc vn cn c gi li v d nh cc lp trong gi java.util nh Stack, Vector v Hastable cng nh Enumeration. H tr i tng Display: ng nh tn gi mt chng trnh MIDP s h tr duy nht mt i tng Display l i tng qun l vic hin th d liu trn mn hnh in thoi. H tr Form v cc giao din ngi dng. H tr Timer v Alert Cung cp tnh nng Record Management System (RMS) cho vic lu tr d liu
Ngoi ra vo thng 11 nm 2003 Sun tung ra MIDP 2.0 vi hng lot tnh nng khc c cung cp thm so vi bn 1.0. Nhng ci tin ni bt so vi MIDP 1.0 Nng cp cc tnh nng bo mt nh o Download qua mng an ton hn qua vic h tr giao thc HTTPS. o Kim sot vic kt ni gia my di ng v server: v d nh cc chng trnh khng th kt ni ti server nu thiu s chp thun ca ngi s dng. Thm cc API h tr Multimedia. Mt trong nhng ci tin hp dn nht ca MIDP 2.0 l tp cc API media ca n. Cc API ny l mt tp con ch h tr m thanh ca Mobile Media API (MMAPI). M rng cc tnh nng ca Form. Nhiu ci tin c a vo API javax.microedition.lcdui trong MIDP 2.0, nhng cc thay i ln nht (ngoi API cho game) l trong Form v Item. H tr cc lp trnh vin Game bng cch tung ra Game API: C l Sun kp nhn ra th trng y tim nng ca cc thit b di ng trong lnh vc Game. Vi MIDP 1.0 th cc lp trnh vin phi t mnh vit code qun l cc hnh ng ca nhn vt cng nh qun l ha. Vic ny s lm tng kch thc file ca sn phm cng nh vic xut hin cc on m b li. c hng li nht t Game API trong MIDP 2.0 khng ch l cc lp trnh vin Game m cn l cc lp trnh vin cn s dng cc tnh nng ha cao cp. tng c bn ca Game API l vic gi nh rng mt mn hnh game l tp hp cc layer (lp). V d nh: trong mt game ua xe th mn hnh nn l mt layer, con ng l mt layer v chic xe c xem nh ang nm trn layer khc. Vi Game API nh pht trin cn c cung cp cc tnh nng nh qun l cc thao tc bn phm. H tr kiu nh RGB: mt trong nhng ci tin hp dn cho cc nh pht trin MIDP l vic biu din hnh nh di dng cc mng s nguyn, cho php MIDlet thao tc vi d liu hnh nh mt cch trc tip.
II.4.2.
MIDLet
MIDP (Mobile Information Device Profile) l tp cc hm API dnh cho thit b thng tin di ng. MIDlet l ng dng MIDP. Thut ng MIDlet v MID application c s dng nh nhau. Cc MIDlets hnh thnh nn cc khi xy dng ca mi trng thc thi Java 2 Platform Micro Edition (J2ME).
18
MIDlet c thit k chy v c iu khin bi trnh qun l ng dng trong my o K (K Virtual Machine - KVM), mt dng n gin nht ca my o Java c thit k chy trn thit b di ng. Lp javax.microedition.midlet.MIDlet hot ng nh l mt giao din (interface) gia MIDlet v trnh qun l ng dng. Cc phng thc thuc lp ny cho php trnh qun l ng dng to, bt u, tm dng, v hy MIDlet.
Thng bo import dng truy xut cc lp ca CLDC v MIDP. Lp chnh ca ng dng c nh ngha l lp k tha lp MIDlet ca MIDP. C th ch c mt lp trong ng dng k tha lp ny. Lp MIDlet c trnh qun l ng dng trn in thoi di ng dng khi ng, dng, v tm dng MIDlet. V d, trong trng hp c cuc gi n. II.4.3. B khung ca MIDlet (MIDlet Skeleton) Mt MIDlet l mt lp Java k tha (extend) ca lp tru tng java.microedition.midlet.MIDlet v thc thi (implement) cc phng thc startApp(), pauseApp(), v destroyApp().
(1) Pht biu import: Cc pht biu import c dng include cc lp cn thit t cc th vin CLDC v MIDP. (2) Phn chnh ca MIDlet: MIDlet c nh ngha nh mt lp k tha lp MIDlet. Trong v d ny MIDletExample l bt u ca ng dng. (3) Hm khi to - Constructor:
19
Hm to ch c thc thi mt ln khi MIDlet c khi to ln u tin. Hm to s khng c gi li tr phi MIDlet thot v sau khi ng li. (4) startApp(): Phng thc startApp() c gi bi b qun l ng dng khi MIDlet c khi to, v mi khi MIDlet tr v t trng thi tm dng. Ni chung, cc bin ton cc s c khi to li tr hm to bi v cc bin c gii phng trong hm pauseApp(). Nu khng th chng s khng c khi to li bi ng dng. (5) pauseApp(): Phng thc pauseApp() c gi bi b qun l ng dng mi khi ng dng cn c tm dng (v d, trong trng hp c cuc gi hoc tin nhn n). Cch thch hp s dng pauseApp() l gii phng ti nguyn v cc bin dnh cho cc chc nng khc trong in thoi trong khi MIDlet c tm dng. Cn ch rng khi nhn cuc gi n h iu hnh trn in thoi di ng c th dng KVM thay v dng MIDlet. Vic ny khng c cp trong MIDP m l do nh sn xut quyt nh s chn cch no. (6) destroyApp(): Phng thc destroyApp() c gi khi thot MIDlet. V d khi nhn nt exit trong ng dng. N ch n thun l thot MIDlet. N khng tht s xa ng dng khi in thoi di ng. Phng thc destroyApp() ch nhn mt tham s Boolean. Nu tham s ny l true, MIDlet c tt v iu kin. Nu tham s l false, MIDlet c thm ty chn t chi thot bng cch nm ra mt ngoi l MIDletStateChangeException. II.4.4. Vng i ca MIDlet (gMIDlet lifecycle) Lp chnh ca mt MIDlet k tha l lp javax.microedition.midlet.MIDlet. Lp chnh ny nh ngha ba phng thc hnh ng trong chu k sng ca n: startApp(), pauseApp(), v destroyApp(). C ba trng thi trong vng i ca mt MIDlet: paused: MIDlet instance c to xong v cha hot ng (inactive) active: MIDlet ang hot ng. destroyed: MIDlet kt thc v sn sng cho vic ti ch bi b thu gom rc. Ch y khng c trng thi no tng ng vi trng thi loaded ca applet, bi v y khng c phng thc khi to. Thng thng, mt MIDlet khi to chnh n ngay ln u tin khi phng thc startApp() c gi.
20
Khi ngi dng yu cu khi ng ng dng MIDlet, b qun l ng dng s thc thi MIDlet (thng qua lp MIDlet). Khi ng dng thc thi, n s c xem l ang trng thi tm dng. B qun l ng dng gi hm to v hm startApp(). Hm startApp() c th c gi nhiu ln trong sut chu k sng ca ng dng. Hm destroyApp() ch c th gi t trng thi hot ng hay tm dng. Lp trnh vin cng c th iu khin trng thi ca MIDlet. Cc phng thc dng iu khin cc trng thi ca MIDlet: resumeRequest(): Yu cu vo ch hot ng. V d: Khi MIDlet tm dng, v mt s kin timer xut hin. notifyPaused(): Cho bit MIDlet t nguyn chuyn sang trng thi tm dng V d: Khi i mt s kin timer. notifyDestroyed(): Sn sng hy. V d: X l nt nhn Exit Lp trnh vin c th yu cu tm dng MIDlet trong khi i mt s kin timer ht hn. Trong trng hp ny, phng thc notifyPaused() s c dng yu cu b qun l ng dng chuyn ng dng sang trng thi tm dng. II.4.5. Tp tin JAR Cc lp bin dch ca ng dng MIDlet c ng gi trong mt tp tin JAR (Java Archive File). y chnh l tp tin JAR c download xung in thoi di ng. Tp tin JAR cha tt c cc tp tin class t mt hay nhiu MIDlet, cng nh cc ti nguyn cn thit. Hin ti, MIDP ch h tr nh dng hnh .png (Portable Network Graphics). Tp tin JAR cng cha tp tin k khai (manifest file) m t ni dung ca MIDlet cho b qun l ng dng.
21
N cng phi cha cc tp tin d liu m MIDlet cn. Tp tin JAR l ton b ng dng MIDlet. MIDlet c th load v triu gi cc phng thc t bt k lp no trong tp tin JAR, trong MIDP, hay CLDC. N khng th truy xut cc lp khng phi l b phn ca tp tin JAR hay vng dng chung ca thit b di ng. M t ni dung ca tp tin JAR: Cc trng yu cu: Manifest-Version // Phin bn tp tin Manifest MIDlet-Name // Tn b MIDlet (MIDlet suite) MIDlet-Version // Phin bn b MIDlet MIDlet-Vendor // Nh sn xut MIDlet MIDlet-<n> for each MIDlet // Tn ca MIDlet MicroEdtion-Profile // Phin bn hin trng MicroEdtion-Configuration // Phin bn cu hnh Tp tin k khai (manifest) v tp tin JAD Tp tin k khai (manifest.mf) v tp tin JAD (Java Application Descriptor) m t cc c im ca MIDlet. S khc bit ca hai tp tin ny l tp tin k khai l mt phn ca tp tin JAR cn tp tin JAD khng thuc tp tin JAR. u im ca tp tin JAD l cc c im ca MIDlet c th c xc nh trc khi download tp tin JAR. Ni chung, cn t thi gian download mt tp tin vn bn nh hn l download mt tp tin JAR. Nh vy, nu ngi dng mun download mt ng dng khng c thit b di ng h tr (v d, MIDP 2.0), th qu trnh download s b hy b thay v phi i download ht ton b tp tin JAR. V d mt tp tin manifest.mf: MIDlet-Name: CardGames MIDlet-Version: 1.0.0 MIDlet-Vendor: Sony Ericsson MIDlet-Description: Set of Card Games MIDlet-Info-URL: http://www.semc.com/games MIDlet-Jar-URL: http://www.semc.com/j2me/games MIDlet-Jar-Size: 1063 MicroEdtion-Profile: MIDP-1.0 MicroEdtion-Configuration: CLDC-1.0 MIDlet-1: Solitaire, /Sol.png, com.semc.Solitaire MIDlet-2: BlackJack, /Blkjk.png, com.semc.BlackJack Tp tin JAD cha cng thng tin nh tp tin manifest. Nhng n nm ngoi tp tin JAR.
22
Cc thuc tnh MIDlet-Name, MIDlet-Version, v MIDlet-Vendor phi c lp li trong tp tin JAD v JAR. Cc thuc tnh khc khng cn phi lp li. Gi tr trong tp tin m t s gi tr ca tp tin manifest. II.4.6. B MIDlet (MIDlet Suite) Mt tp cc MIDlet trong cng mt tp tin JAR c gi l mt b MIDlet (MIDlet suite). Cc MIDlet trong mt b MIDlet chia s cc lp, cc hnh nh, v d liu lu tr bn vng. cp nht mt MIDlet, ton b tp tin JAR phi c cp nht.
Trong hnh trn, mt b MIDlet cha MIDlet1, MIDlet2, v MIDlet3. B kia ch cha MIDlet4. Ba MIDlet trong b u tin truy xut cc lp v d liu ca nhau nhng khng truy xut n cc lp hay d liu ca MIDlet4. Ngc li, MIDlet4 cng khng truy xut c cc lp, hnh nh, v d liu ca chng.
23
- Chy file sun_java_wireless_toolkit-2_5_1-windows.exe ci t chng trnh. Sau khi ci t thnh cng, bn s c th mc chng trnh trong menu Start nh hnh bn di chy chng trnh chng ta chn wireless Toolkit 2.5.1. Bn s thy ca s hin ra nh hnh bn di
Chng trnh Hello u tin - Chng ta click chut vo New project v nhp vo Project v Class bn mun to vidu: TestMidlet v khng nht thit tn Class trng vi tn Project - T Target Platform chn Custom. V d chng ta mun ng dng thch hp vi in thoi N70 cho nn trong group MIDP 2.0 v CLDC 1.1, chng ta c th tra cu flatform ti y http://www.forum.nokia.com/devices/matrix_s60_1.html
24
ToolKit s t ng to 1 th mc con trong th mc apps c tn trng vi tn Project m bn va to, trong trng hp ny l TestMidlet.
25
Cc th mc trong d n: - Bin: Cha 2 file ci t, .Jar ( Java ARchive) v file miu t .jad. - Lib: Cha cc th vin b sung m bn mun thm vo chng trnh. - Res: l th mc bn cc file ti nguyn dnh ring cho chng trnh nh file vn bn v hnh nh. - Src: y l th mc quan trng nht, l ni bn t cc file cha m ngun. By gi chng ta dng chng trnh son tho vn bn no v vit:
import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class TestMidle extends MIDlet implements CommandListener { private Form mMainForm; public TestMidlet() { mMainForm = new Form("Chuong trinh so 1"); mMainForm.append(new StringItem(null, "Chao cac ban, MIDP!")); mMainForm.addCommand(new Command("Exit", Command.EXIT, 0)); mMainForm.setCommandListener(this); } public void startApp() { Display.getDisplay(this).setCurrent(mMainForm); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable s) {
26
- Sau , hy lu on code trn vo file tn l TestMidlet.java trong th mc src. - Bm vo nt Build, nu code ca bn khng b li, bn s nhn c thng bo sau: Project settings saved; Building "TestMidlet"; Build complete. - Nhn nt Run chy Emulator - Nu bn thy trn my bn xut hin hnh nh hnh bn di th xin chc mng bn. Chng trnh J2ME u tin chy thnh cng.
27
II.5.2.
Import Wireless toolkit project sang Netbeans - Trc tin ta cn phi c module Netbeans_mobility 5.5.1 gn vo Netbeans 5.5.1, bn c th download ti y http://dlc.sun.com/netbeans/download/5_ ... 704122300/ - Chy file netbeans_mobility-5_5_1-windows_2.exe ci t - y l dao din khi khi ng Netbeans
- Bc 1: Chn File -> New Project - Bc 2: trong Categories chn Mobile v trong Projects chn Import Wireless Toolkit Project, sau chn Next - Bc 3: Browse ti th mc C:\WTK2.5.1\apps (ni ci t Wireless Toolkit) chn TestMidlet sau chn Open -> Next.
28
ng chn tng ng vi Midlet v CLDC bn Project ca Wireless Toolkit, tuy nhin chng ta c th chn theo mc ch ring ca mnh m khng lm nh hng ti Project ngun bn Wireless Toolkit v Netbeans s t ng copy Project ngun sang dng Project ca Netbeans sau mi ln bin dch. Ngi lp trnh c th edit code trn Project ngun hay Project ca Netbeans ty . Cui cng l chn Finish.
- build chng trnh chng ta c th vo Build -> Build Main Project v Run -> Run Main Project chy chng trnh
ny s c tha k bi cc thnh phn hin th mc cao, chnh cc thnh phn ny s c hin th ra trn mn hnh. Hnh di y s m t mi quan h ca lp Screen v cc thnh phn th hin mc cao.
Tm li, phn ny ch gii thiu h thng phn cp i tng dng th hin giao din ngi dng trong MIDP.
a) DateField
31
Thnh phn DateField cung cp mt phng tin trc quan thao tc i tng Date c nh ngha trong java.util.Date. Khi to mt i tng DateField, bn cn ch r l ngi dng ch c th chnh sa ngy, chnh sa gi hay ng thi c hai. Cc phng thc dng ca lp DateField gm:
D ateF ield (S tring lab el, in t m o de) D ateF ield (S tring lab el, in t m o de, Tim eZone tim eZone)
Cc mode tng ng ca lp DateField gm:
D ateF ield .D A T E_T IM E :cho php thay i ngy gi D ateF ield .T IM E: ch cho php thay i gi D ateF ield .D A T E: ch cho php thay i ngy
V d:
private DateField dfAlarm; // To mt i tng DateField vi nhn, cho php thay i c ngy v gi Alarm = new DateField("Set Alarm Time", DateField.DATE_TIME); dfAlarm.setDate(new Date());
32
b) Gauge
Mt thnh phn Gauge l mt kiu giao din thng c dng m t mc hon thnh mt cng vic. C 2 loi Gauge l loi tng tc v loi khng tng tc. Loi u cho php ngi dng c th thay i Gauge, loi 2 th i hi ngi pht trin phi cp nht Gauge Di y l hm dng ca lp Gauge:
G auge(String label, boolean interactive, int maxValue, int initialValue)
V d:
private Gauge gaVolume; // iu chnh m lng gaVolume = new Gauge("Sound Level", true, 100, 4);
33
// Create form, add commands, listen for events fmMain = new Form(""); fmMain.addCommand(cmExit); fmMain.append(gaVolume); fmMain.setCommandListener(this); } // Called by application manager to start the MIDlet. public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } }
c) StringItem
Mt thnh phn StringItem c dng hin th mt nhn hay chui vn bn. Ngi dng khng th thay i nhn hay chui vn bn khi chng trnh ang chy. StringItem khng nhn ra s kin Phng thc dng ca lp StringItem StringItem(String label, String text) Di y l on m minh ha vic s dng i tng StringItem import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class StringItemTest extends MIDlet implements CommandListener { private Display display; // Reference to Display object private Form fmMain; // 34
Mobile Programming (Private Version) Main form private StringItem siMsg; // StringItem private Command cmChange; // Change the label and message private Command cmExit; // Exit the MIDlet public StringItemTest() { display = Display.getDisplay(this); // Create text message and commands siMsg = new StringItem("Website: ", "www.IBM.com"); cmChange = new Command("Change", Command.SCREEN, 1); cmExit = new Command("Exit", Command.EXIT, 1);
// Create Form, add Command and StringItem, listen for events fmMain = new Form("StringItem Test"); fmMain.addCommand(cmExit); fmMain.addCommand(cmChange); fmMain.append(siMsg); fmMain.setCommandListener(this) ; } // Called by application manager to start the MIDlet. public void startApp() { display.setCurrent(fmMain); }
public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmChange) { // Change label siMsg.setLabel("Section : "); // Change text siMsg.setText("developerWor ks");
35
Mobile Programming (Private Version) // Remove the command fmMain.removeCommand(cmChange); } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } }
d) TextField
Mt thnh phn TextField th tng t nh bt k cc i tng nhp vn bn tiu biu no. Bn c th ch nh mt nhn, s k t ti a c php nhp, v loi d liu c php nhp. Ngoi ra TextField cn cho php bn nhp vo mt khu vi cc k t nhp vo s c che bi cc k t mt n Phng thc dng ca lp TextField TextField(String label, String text, int maxSize, int constraints) Thnh phn th 3 constraints l thnh phn m chng ta quan tm, v n l phng tin xc nh loi d liu no c php nhp vo TextField MIDP nh ngha cc tham s rng buc sau cho thnh phn TextField: ANY: cho php nhp bt k k t no EMAILADDR: ch cho php nhp vo cc a ch email hp l NUMERIC: ch cho php nhp s PHONENUMBER: Ch cho php nhp s in thoi URL: Ch cho php nhp cc k t hp l bn trong URL PASSWORD: che tt c cc k t nhp vo Di y l on m minh ha vic s dng thnh phn TextField import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TextFieldTest extends MIDlet implements CommandListener { private Display display; // Reference to Display object private Form fmMain;// Main form private Command cmTest; // Get contents of textfield private Command cmExit; // Command to exit the MIDlet private TextField tfText; // Textfield public TextFieldTest() { display = Display.getDisplay(this); // Create commands cmTest = new Command("Get Contents", Command.SCREEN, 1); 36
// Textfield for phone number tfText = new TextField("Phone:", "", 10, TextField.PHONENUMBER); // Create Form, add Commands and textfield, listen for events fmMain = new Form("Phone Number"); fmMain.addCommand(cmExit); fmMain.addCommand(cmTest); fmMain.append(tfText); fmMain.setCommandListener(this); } // Called by application manager to start the MIDlet. public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmTest) { System.out.println("TextField contains: " + tfText.getString()); } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } } on m trn ch mi p dng mt rng buc trn i tng TextField. Chng ta c th thm mt rng buc th 2 bng cch: tfText = new TextField("Phone:", "", 10, TextField.PHONENUMBER | TextField.PASSWORD);
e) ChoiceGroup
Thnh phn ChoiceGroup cho php ngi dng chn t mt danh sch u vo c nh ngha trc. ChoiceGroup c 2 loi: multi-selection(cho php chn nhiu mc): nhm ny c lin quan n cc 37
checkbox exclusive-selection(ch c chn mt mc): nhm ny lin quan n nhm cc radio button Di y l on m minh ha cho vic s dng ChoiceGroup: import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ChoiceGroupTest extends MIDlet implements ItemStateListener, CommandListener { private Display display; // Reference to display object private Form fmMain; // Main form private Command cmExit; // A Command to exit the MIDlet private Command cmView; // View the choice selected private int selectAllIndex; // Index of the "Select All" option private ChoiceGroup cgPrefs; // Choice Group of preferences private int choiceGroupIndex; // Index of choice group on form public ChoiceGroupTest() { display = Display.getDisplay(this); // Create a multiple choice group cgPrefs = new ChoiceGroup("Preferences", Choice.MULTIPLE); // Append options, with no associated images cgPrefs.append("Replace tabs with spaces", null); cgPrefs.append("Save bookmarks", null); cgPrefs.append("Detect file type", null); selectAllIndex = cgPrefs.append("Select All", null); cmExit = new Command("Exit", Command.EXIT, 1); cmView = new Command("View", Command.SCREEN,2); // Create Form, add components, listen for events fmMain = new Form(""); choiceGroupIndex = fmMain.append(cgPrefs); fmMain.addCommand(cmExit); fmMain.addCommand(cmView); fmMain.setCommandListener(this); fmMain.setItemStateListener(this); } public void startApp() 38
Mobile Programming (Private Version) { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { }
public void commandAction(Command c, Displayable s) { if (c == cmView) { boolean selected[] = new boolean[cgPrefs.size()]; // Fill array indicating whether each element is checked cgPrefs.getSelectedFlags(selected); for (int i = 0; i < cgPrefs.size(); i++) System.out.println(cgPrefs.getSt ring(i) + (selected[i] ? ": selected" : ": not selected")); } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } public void itemStateChanged(Item item) { if (item == cgPrefs) { // Is "Select all" option checked ? if (cgPrefs.isSelected(selectAllIndex)) { // Set all checkboxes to true for (int i = 0; i < cgPrefs.size(); i++) cgPrefs.setSelectedIndex(i, true); // Remove the check by "Select All" cgPrefs.setSelectedIndex(selectAllIndex, false); } } } 39
f) Spacer
Spacer l thnh phn khng nhn thy, c dng nh v tr cho cc i tng khc trn mn hnh hin th. Bn c th dng Spacer ch r khong trng theo chiu dc v chiu ngang gia cc thnh phn, n gin bng cch ch ra chiu di v chiu rng cho tng ci. V Spacer l thnh phn khng nhn thy nn n khng c s kin
public class ImageTest extends MIDlet implements CommandListener { private Display display; // Reference to Display object private Form fmMain; // The main form private Command cmExit; // Command to exit the MIDlet
public ImageTest() { display = Display.getDisplay(this); cmExit = new Command("Exit", Command.EXIT, 1); fmMain = new Form(""); fmMain.addCommand(cmExit); fmMain.setCommandListener(this); try { // Read the appropriate image based on color support Image im = Image.createImage((display.isColor()) ? "/image_color.png":"/image_bw.png "); fmMain.append(new ImageItem(null, im, ImageItem.LAYOUT_CENTER, null)); display.setCurrent(fmMain); } catch (java.io.IOException e) { System.err.println("Unable to locate or read .png file"); } } public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { }
41
public void commandAction(Command c, Displayable s) { if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } } h. CustomItem Thnh phn CustomItem cho php bn to ra nhng thnh phn Item ca chnh bn. Nhng thnh phn ny cng ging nh nhng Item khc l cng c th c t vo trong Form v c th nhn bit v x l s kin CustomItem c v ln mn hnh hin th bng phng thc paint(). V th n s ty thuc vo on m c bn hin thc bn trong phng thc paint(). Qu trnh to ra mt i tng CustomItem cng khng khc cc i tng c sn trn nn Java. on m di y minh ha sn ca vic to ra mt i tng CustomItem public class NewItem extends CustomItem { public NewItem(String label) { super(label); ... } protected void paint(Graphics g, int width, int height) { ... } protected int getMinContentHeight() { ...; } protected int getMinContentWidth() { ... } protected int getPrefContentHeight(int width) { ... }
a) List
Mt List cha mt dy cc la chn c th hin mt trong ba dng. Chng ta thy loi cho php nhiu la chn v loi ch c php chn mt khi lm vic vi ChoiceGroup. Dng th 3 l l dng khng tng minh. Cc List khng tng minh uc dng th hin mt thc n cc chn la. on m di y minh ha vic s dng mt danh sch khng tng minh import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ImplicitList extends MIDlet implements CommandListener { private Display display; // Reference to Display object private List lsDocument; // Main list private Command cmExit; // Command to exit 43
Mobile Programming (Private Version) public ImplicitList() { display = Display.getDisplay(this); // Create the Commands cmExit = new Command("Exit", Command.EXIT, 1); try { // Create array of image objects Image images[] = {Image.createImage("/next.png"), Image.createImage("/previous.png "), Image.createImage("/new.png")}; // Create array of corresponding string objects String options[] = {"Next", "Previous", "New"};
// Create list using arrays, add commands, listen for events lsDocument = new List("Document Option:", List.IMPLICIT, options, images); // If you have no images, use this line to create the list // lsDocument = new List("Document Option:", List.IMPLICIT, options, null); lsDocument.addCommand(cmEx it); lsDocument.setCommandListener (this); } catch (java.io.IOException e) { System.err.println("Unable to locate or read .png file"); } } public void startApp() { display.setCurrent(lsDocument); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } 44
public void commandAction(Command c, Displayable s) { // If an implicit list generated the event if (c == List.SELECT_COMMAND) { switch (lsDocument.getSelected Index()) { case 0: System.out.println("Next selected"); break; case 1: System.out.println("Previous selected"); break; case 2: System.out.println("New selected"); break; } } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } }
b) TextBox
TextBox c dng cho php nhp nhiu dng. Thnh phn TextBox v TextField c nhng rng buc ging nhau trong vic ch nh loi ni dung c php nhp vo. V d ANY, EMAIL, URI Di y l phng thc dng ca mt TextBox: TextBox(String title, String text, int maxSize, int constraints); Di y l on m minh ha cho vic s dng TextBox: import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TextBoxTest extends MIDlet implements CommandListener { private Display display; // Reference to 45
Mobile Programming (Private Version) Display object private TextBox tbClip; // Main textbox private Command cmExit; // Command to exit public TextBoxTest() { display = Display.getDisplay(this); // Create the Commands. Notice the priorities assigned cmExit = new Command("Exit", Command.EXIT, 1);
tbClip = new TextBox("Textbox Test", "Contents go here..",125, TextField.ANY); tbClip.addCommand(cmExit); tbClip.setCommandListener(this); } public void startApp() { display.setCurrent(tbClip); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } }
c) Alert v AlertType
Mt Alert n gin l mt hp thoi rt nh. C 2 loi Alert: Modal: l loi hp thoi thng bo c trnh by cho n khi ngi dng n nt ng Non-modal: l loi hp thoi thng bo ch c trnh by trong mt s giy nht 46
nh Cc phng thc dng ca Alert: Alert(String title) Alert(String title, String alertText, Image alertImage, AlertType alertType) Thnh phn AlertType s dng m thanh thng bo cho ngi dng bit c mt s kin xy ra. V d bn c th s dng AlertType m mt on m thanh no bo hiu cho ngi dng bit khi c li xy ra. Thnh phn AlertType bao gm 5 loi m thanh nh sn l: thng bo, xc nhn, bo li, thng bo v cnh bo. Ta thy cc phng thc dng ca Alert cho bit l Alert c th bao gm 1 tham chiu n mt i tng AlertType. Di y l on m minh ha vic s dng Alert v AlertType import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class AlertTest extends MIDlet implements ItemStateListener, CommandListener { private Display display; // Reference to display object private Form fmMain; // Main form private Command cmExit; // Command to exit the MIDlet private ChoiceGroup cgSound; // Choice group public AlertTest() { display = Display.getDisplay(this); // Create an exclusive (radio) choice group cgSound = new ChoiceGroup("Choose a sound", Choice.EXCLUSIVE); // Append options, with no associated images cgSound.append("Info", null); cgSound.append("Confirmation", null); cgSound.append("Warning", null); cgSound.append("Alarm", null); cgSound.append("Error", null); cmExit = new Command("Exit", Command.EXIT, 1); // Create Form, add components, listen for events fmMain = new Form(""); fmMain.append(cgSound); fmMain.addCommand(cmExit) ; fmMain.setCommandListener 47
Mobile Programming (Private Version) (this); fmMain.setItemStateListen er(this); } public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { }
public void commandAction(Command c, Displayable s) { if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } public void itemStateChanged(Item item) { Alert al = null; switch (cgSound.getSelectedIndex()) { case 0: al = new Alert("Alert sound", "Info sound", null, AlertType.INFO); break; case 1: al = new Alert("Alert sound", "Confirmation sound", null, AlertType.INFO); break; case 2: al = new Alert("Alert sound", "Warning sound", null, AlertType.INFO); break; case 3: 48
Mobile Programming (Private Version) al = new Alert("Alert sound", "Alarm sound", null, AlertType.INFO); break; case 4: al = new Alert("Alert sound", "Error sound", null, AlertType.INFO); break; } if (al != null) { // Wait for user to acknowledge the alert al.setTimeout(Alert.FOREVER); // Display alert, show main form when done display.setCurrent(al, fmMain); } } }
d) Ticker
Thnh phn Ticker uc dng th hin mt on chui chy theo chiu ngang. Tham s duy nht ca thnh phn Ticker l on vn bn c trnh by. Tc v chiu cun c xc nh bi vic ci t trn thit b no. Phng thc dng ca Ticker Ticker(String str); T cy phn cp cc thnh phn th hin trn thit b, ta thy l thnh phn Ticker khng l lp con ca lp Screen m Ticker l mt bin ca lp Screen. iu ny c ngha l mt Ticker c th c gn vo bt c lp con ca lp Screen bao gm c Alert Di y l on m minh ha vic s dng mt Ticker import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class TickerTest extends MIDlet implements CommandListener { private Display display; // Reference to Display object private List lsProducts; // Products private Ticker tkSale; // Ticker private Command cmExit; // Command to exit the MIDlet
49
Mobile Programming (Private Version) public TickerTest() { display = Display.getDisplay(this); cmExit = new Command("Exit", Command.SCREEN, 1);
tkSale = new Ticker("Sale: Real Imitation Cuban Cigars...10 for $10"); lsProducts = new List("Products", Choice.IMPLICIT); lsProducts.append("Wicker Chair", null); lsProducts.append("Coffee Table", null); lsProducts.addCommand(cmExit) ; lsProducts.setCommandListener (this); lsProducts.setTicker(tkSale); } public void startApp() { display.setCurrent(lsProducts); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == List.SELECT_COMMAND) { switch (lsProducts.getSelectedIndex()) { case 0: System.out.println("Chair selected"); break; case 1: System.out.println("Table selected"); break; } } 50
IV.2. Lp Canvas
Lp Canvas cung cp mt khung v cho php to ra giao din ty bin ngi dng. Mt s lng ln cc phng thc trong lp ny c dng x l s kin, v nh v chui ln thit b hin th. Trong phn ny s bao gm cc mc H thng ta To i tng Canvas V ln trn i tng Canvas X l cc s kin hnh ng X l cc s kin phm nhn X l s kin hnh ng ca Game X l s kin con tr Chng ta s to ra 2 ng dng MIDlet minh ha kh nng ca lp Canvas. ng dng u tin l KeyMapping s minh ha lm th no chp, nhn ra v x l m phm nhn v cc s kin c lin quan n Game. ng dng cn li l ScratchPad s minh ha lm th no thao tc cc s kin con tr to ra mt chng trnh v ng thng n gin
a) H thng trc ta
Mc tiu u tin ca chng ta l lm quen vi h thng trc ta lm 51
vic vi thit b th hin. H thng ta cho lp Canvas c tm ta l im tri trn ca thit b trnh by. Gi tr x tng dn v pha phi, gi tr y tng dn khi i xung pha di. Khi v dy bt v l mt im nh
Cc phng thc sau y s gip xc nh chiu rng v chiu cao ca canvas: int getWidth(): xc nh chiu rng ca canvas int getHeight (): xc nh chiu cao ca canvas Chiu rng v chiu cao ca Canvas cng i din cho ton b din tch khung v c th trn thit b trnh by. Ni cch khc, bn khng th ch nh kch thc cho canvas, m phn mm trn mt thit b MIDP s tr v din tch ln nht c th c i vi mt thit b cho trc
b) To mt i tng Canvas
Bc u tin lm vic vi mt lp Canvas l to ra mt lp tha k t lp Canvas class TestCanvas extends Canvas implements CommandListener { private Command cmdExit; ... display = Display.getDisplay(this); cmdExit = new Command("Exit", Command.EXIT, 1); addCommand(cmdExit); setCommandListener(this); ... protected void paint(Graphics g) { // Draw onto the canvas ... 52
d) S kin hnh ng
Cng nh cc thnh phn Form, List, v TextBox, mt Canvas c th x l cc s Command. Chng ta c th x l cc s kin Command trn thnh phn Canvas cung cch nh cc thnh phn khc on m sau minh ha vic x l s kin Command trn thnh phn Canvas class TestCanvas extends Canvas implements CommandListener { private Command cmdExit; ... display = Display.getDisplay(this); cmdExit = new Command("Exit", Command.EXIT, 1); addCommand(cmdExit); setCommandListener(this); ... protected void paint(Graphics g) { // Draw onto the canvas ... } public void commandAction(Command c, Displayable d) { if (c == cmdExit) ... } } 53
e) M phm
Trong trng hp x l cc hnh ng ca cc phm mm, mt Canvas c th truy cp n 12 m phm. Nhng m ny c m bo lun lun c trn bt k cc thit b MIDP no K E Y _N U M 0 K E Y _N U M 1 K E Y _N U M 2 K E Y _N U M 3 K E Y _N U M 4 K E Y _N U M 5 K E Y _N U M 6 K E Y _N U M 7 K E Y _N U M 8 K E Y _N U M 9 K E Y _S TA R K E Y _P O U N D Nm phng thc x l cc m phm l: void keyPressed(int keyCode); void keyReleased(int keyCode); void keyRepeated(int keyCode); boolean hasRepeatEvents(); String getKeyName(int keyCode);
54
g) Xc nh cc hnh ng ca tr chi
on m sau y m t mt cch xc nh cc hnh ng ca tr chi t gi cc phng thc thch hp da trn cc hnh ng xy ra
protected void keyPressed(int keyCode) { switch (getGameAction(keyCode)) { case Canvas.FIRE: shoot(); break; case Canvas.RIGHT: goRight(); break; ... } } Mt la chn na l c th to mt tham chiu cho mi hnh ng ca tr chi thng qua qu trnh khi to gi tr cho cc bin // Initialization keyFire = getKeyCode(FIRE); 55
// Runtime protected void keyPressed(int keyCode) { if (keyCode == keyFire) shoot(); else if (keyCode == keyRight) goRight() ... } on m di y minh ha mt s chc nng ca Canvas v cch x l phm import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class KeyMapping extends MIDlet { private Display display; // The display private KeyCodeCanvas canvas; // Canvas public KeyMapping() { display = Display.getDisplay(this); canvas = new KeyCodeCanvas(this); } protected void startApp() { display.setCurrent( canvas ); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } 56
/*-------------------------------------------------* Class KeyCodeCanvas *-------------------------------------------------*/ class KeyCodeCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private String keyText = null; // Key code text private KeyCodes midlet; /*------------------------ -------------------------* Constructor *------------------------- ------------------------*/ public KeyCodeCanvas(KeyCodes midlet) { this.midlet = midlet; // Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); } /*------------------------ -------------------------* Paint the text representing the key code *------------------------- ------------------------*/ protected void paint(Graphics g) { // Clear the background (to white) g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight()); // Set color and draw text if (keyText != null) { // Draw with black pen g.setColor(0, 0, 0); // Center text g.drawString(keyText, getWidth()/2, getHeight()/2, Graphics.TOP | Graphics.HCENTER); } } 57
/*------------------------ -------------------------* Command event handling *------------------------- ------------------------*/ public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); } /*------------------------ -------------------------* Key code event handling *------------------------- ------------------------*/ protected void keyPressed(int keyCode) { keyText = getKeyName(keyCode); repaint(); } }
h) S kin con tr
Trong phn ny chng ta s qun l s kin con tr trong mt Canvas. Nhng s kin ny c thit k lm thun tin cho vic tng tc vi cc thit b c dng con tr. Mt s phng thc c cung cp nhm h tr cho vic x l s kin con tr:
boolean hasPointerEvents() ; boolean hasPointerMotionEvents() ; void pointerPressed(int x, int y); void pointerReleased(int x, int y); void pointerDragged(int x, int y); Cc phng thc trn c th t gii thch chc nng thng qua tn ca chnh mnh. Phng thc hasPointerMotionEvents() tr v mt gi tr c kiu boolean nhm ch r rng thit b di ng c h tr khi nim nhp chut v r hay khng. on chng trnh di y minh ha vic s dng cc s kin con tr thc hin mt chng trnh v n gin import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class ScratchPad extends MIDlet { private Display display; // Display object private ScratchPadCanvas canvas; // Canvas public ScratchPad() { display = Display.getDisplay(this); 58
protected void startApp() { display.setCurrent( canvas ); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } /*-------------------------------------------------* Class ScratchPadCanvas * * Pointer event handling *-------------------------------------------------*/ class ScratchPadCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private Command cmClear; // Clear display private int startx = 0, // Where pointer was clicked starty = 0, currentx = 0, // Current location currenty = 0; private ScratchPad midlet; private boolean clearDisplay = true; /*-------------------------------------------------* Constructor *-------------------------------------------------*/ public ScratchPadCanvas(ScratchPad midlet) { this.midlet = midlet; // Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); cmClear = new Command("Clear", Command.SCREEN, 1); addCommand(cmExit); addCommand(cmClear); 59
Mobile Programming (Private Version) setCommandListener(this ); } /*-------------------------------------------------* Draw line based on start and ending points *-------------------------------------------------*/ protected void paint(Graphics g) { // Clear the background (to white) if (clearDisplay) { g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight()); clearDisplay = false; startx = currentx = starty = currenty = 0; return; } // Draw with black pen g.setColor(0, 0, 0); // Draw line g.drawLine(startx, starty, currentx, currenty); // New starting point is the current position startx = currentx; starty = currenty; } /*-------------------------------------------------* Command event handling *-------------------------------------------------*/ public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet() ; else if (c == cmClear) { clearDisplay = true; repaint(); } } /*-------------------------------------------------* Pointer pressed *-------------------------------------------------*/ protected void pointerPressed(int x, int y)
60
Mobile Programming (Private Version) { startx = x; starty = y; } /*-------------------------------------------------* Pointer moved *-------------------------------------------------*/ protected void pointerDragged(int x, int y) { currentx = x; currenty = y; repaint(); } }
IV.3. Lp Graphics
Chng ta s dng i tng Graphics v ln mt Canvas.
a) H tr mu
Mt ng dng MIDP ch c mt i tng Display. i tng ny uc dng ly thng tin ca mn hnh hin th hin ti, v d nh s mu h tr v cc phng thc yu cu cc i tng c hin th. i tng Display n gin l mt b qun l s hin th ca thit b v iu khin nhng g s c hin th ra trn thit b. boolean isColor(); int numColors(); Phng thc u tin cho bit thit b c h tr hin th mu hay khng. Nu c th phng thc th 2 s c gi xc nh s mu c h tr. Cc phng thc tip theo di y ly v mu v thit lp mu a thch ca bn. void setColor(int RGB); void setColor(int red, int green, int blue); int getColor(); int getBlueComponent(); int getGreenComponent(); int getRedComponent(); void setGrayScale(int value); int getGrayScale(); 61
Ch bn c th xc nh mu bng 2 cch. Cch 1: bn c th xc nh mt s nguyn i din cho 3 gi tr ca mu l , xanh l cy v xanh dng vi 8 bit cho mi mu. Hay cch 2 l bn c th dng tng tham s ring bit xc nh mi mu. Khi s dng mt gi tr lu gi mu, th mu s chim 8 bit u k t bn tri, tip theo l 8 bit dnh cho mu xanh l cy, sau cng l mu xanh dng. Di y s hng dn bn cch thit lp mu ch s dng mt s nguyn: int red = 0, green = 128, blue = 255; ... g.setColor((red << 16) | (green << 8) | blue); V bn c th xc nh mu bng cch thit lp gi tr cho 3 tham s:
g.setColor(red, green, blue);
b) Loi nt v
Bn c th chn nt khi v ng thng, cung v hnh ch nht trn thit b hin th. Di y l cc phng thc dng thit lp loi nt v int getStrokeStyle(); void setStrokeStyle(int style); Hai kiu nt v c nh ngha trong lp Graphics l nt chm, v nt lin g.setStrokeStyle(Graphics.DOTTED); hay g.setStrokeStyle(Graphics.SOLID);
c) V cung
Khi v mt cung, bn c th v n ch c ng bao xung quanh hay yu cu n c t bn trong. Bn c th bt u bng cch ch nh chiu bao quanh bn ngoi ca mt hnh hp ch nht tng tng. Gc bt u xc nh v tr bt u v khung, vi gi tr 0 c xc nh ti thi im 3 gi. Gi tr dng tnh theo ngc chiu kim ng h. Gc ca cung ch ra rng c bao nhiu c v tnh t gc ban u, i theo ngc chiu kim ng h. hiu r nhng phn ny chng ta hy cng xem1 v d sau: g.draw A rc(10, 10, 100, 100, 0, 150); on m trn yu cu v mt cung, cung ny c bao bi mt hnh ch nht c ta im tri trn l (10, 10), chiu rng v chiu di l 100, gc bt u l 0, gc kt thc l 150
62
Mt s cc phng thc dng v cung void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle); void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle); Di y l on m minh ha vic s dng cc hm trn v mt cung import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class DrawShapes extends MIDlet { private Display display; // The display private ShapesCanvas canvas; // Canvas public DrawShapes() { display = Display.getDisplay(this); canvas = new ShapesCanvas(this); } protected void startApp() { display.setCurrent( canvas ); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } }
63
/*-------------------------------------------------* Class ShapesCanvas * * Draw arcs *-------------------------------------------------*/ class ShapesCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private DrawShapes midlet; public ShapesCanvas(DrawShapes midlet) { this.midlet = midlet; // Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); } /*-------------------------------------------------* Draw shapes *-------------------------------------------------*/ protected void paint(Graphics g) { // Clear background to white g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight()); // Black pen g.setColor(0, 0, 0); // Start at 3 o'clock and rotate 150 degrees g.drawArc(10, 10, 100, 100, 0, 150); // Fill the arc // g.fillArc(10, 10, 100, 100, 0, 150); // Start at 12 o'clock and rotate 150 degrees // g.drawArc(10, 10, 100, 100, 90, 150);
// Change the size of the bounding box // Start at 12 o'clock and rotate 150 degrees 64
Mobile Programming (Private Version) // } g.drawArc(15, 45, 30, 70, 90, 150);
d) V hnh ch nht
Cng ging nh cung th hnh ch nht c th ch c v vin bao quanh hoc t bn trong. Bn cnh bn c th v hnh ch nht c 4 gc l trn hoc l vung. Di y l mt s phng thc v hnh ch nht: void drawRect(int x, int y, int width, int height); void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight); void fillRect(int x, int y, int width, int height); void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight); Khi v hnh ch nht c 4 gc l trn th bn phi xc nh ng knh theo chiu ngang(arcWidth) v ng knh theo chiu dc(arcHeight). Nhng tham s ny c nh ngha sc nt ca cung theo mi chiu. Gi tr cng ln th hin mt cung tng dn, ngc li l mt ng cong hp
e) Font ch
Phn sau y cng quan trng khng km l cch s dng font ch c h tr bi giao din cp thp ca ng dng MIDP. Sau y l mt s cc phng thc dng ca lp Font Font getFont(int face, int style, int size) ; Font getFont(int fontSpecifier) ; Font getDefaultFont() ; Mt s thuc tnh ca lp Font FACE_SYSTEM FACE_MONOSPACE FACE_PROPORTIONAL STYLE_PLAIN STYLE_BOLD STYLE_ITALIC STYLE_UNDERLINED SIZE_SMALL SIZE_MEDIUM SIZE_LARGE Cc tham s kiu dng c th c kt hp thng qua ton t hay. V d Font font = Font.getFont(Font.FACE_PROPOR TIONAL, Font.STYLE_BOLD | Font.STYLE_ITALIC, Font.SIZE_MEDIUM); Sau khi bn c mt tham chiu n mt i tng Font, bn c th truy vn n xc nh thng tin ca cc thuc tnh ca n. 65
int getFace(); int getStyle(); int getSize(); boolean isPlain(); boolean isBold(); boolean isItalic(); boolean isUnderlined(); Kch thc ca cc font ch c xc nh bi chiu cao ca font ch, b di tnh bng im nh ca mt chui k t trong mt font xc nh. Mt s cc phng thc sau h tr khi tng tc vi mt i tng font int getHeight(); int getBaselinePosition(); int charWidth(char ch); int charsWidth(char[] ch, int offset, int length); int stringWidth(String str); int substringWidth(String str, int offset, int length);
f) im neo
xc nh ta x, y ca chui k t c hin th, th im neo cho php bn ch ra v tr mun t ta x, y trn hnh ch nht bao quanh chui k t
C 6 im neo c nh ngha trc, 3 theo chiu dc v 3 theo chiu thng ng, Khi xc nh im neo v chui (cc im neo thng c s dng thnh tng cp), bn phi chn mt im honh v mt im tung . Cc im neo c nh ngha nh di y Chiu ngang LEFT (Bn tri) CENTER (Chnh gia ca chiu ngang) RIGHT (Bn phi) Chiu dcs TOP ( trn) BASELINE (ng thng c s) BOTTOM ( di) Khi s dng im neo th bn cn phi ch ra ta x, y ca hnh ch nht bao quanh. V d g.drawString("developerWorks", 0, 0 , Graphics.TOP | Graphics.LEFT); 66
Hnh di y m t kt qu ca hm trn
Bng cch thay i im neo, chng ta c th thay i v tr hin th ca chui k t trn thit b di ng. V d tip theo chng ta s minh ha tip khi thay i im neo th v tr ca chui k t cng thay i theo: g.drawString("developerWorks", 0, 0 , Graphics.TOP | Graphics.HCENTER);
g) V cc chui k t
Sau khi tm hiu v font v cc im neo, bn c th v chui k t ra mn hnh thng qua mt s cc phng thc sau: void drawChar(char character, int x, int y, int anchor) void drawChars(char[] data, int offset, int length, int x, int y, int anchor) void drawString(String str, int x, int y, int anchor) void drawSubstring(String str, int offset, int len, int x, int y, int anchor) V d: protected void paint(Graphics g) { // Get center of display int xcenter = getWidth() / 2, ycenter = getHeight() / 2; 67
// Choose a font g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_ITALICS, Font.SIZE_MEDIUM)); // Specify the center of the text (bounding box) using the anchor point g.drawString("developerWorks", xcenter, ycenter, Graphics.BASELINE | Graphics.HCENTER); } Tip theo l v d minh ha vic s dung font v xut chui ra thit b hin th import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class FontViewer extends MIDlet { protected Display display; // The display protected PrefsForm fmPrefs; // Form to choose font prefs protected FontCanvas cvFont; // Canvas to display text (in preferred font) public FontViewer() { display = Display.getDisplay(this); cvFont = new FontCanvas(this); fmPrefs = new PrefsForm("Preferences", this); } protected void startApp() { showCanvas(); } protected void showCanvas() { display.setCurrent(cvFont); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } 68
/*-------------------------------------------------* FontCanvas.java * * Draw text using specified Font *-------------------------------------------------*/ import javax.microedition.lcdui.*; class FontCanvas extends Canvas implements CommandListener { private int face, // Font face style // sty , size; // le siz e private String text = "developerWorks"; // Text to display in preferred font private Command cmExit; // Exit midlet private Command cmPrefs; // Call the preferences form private FontViewer midlet; // Reference to the main midlet public FontCanvas(FontViewer midlet) { this.midlet = midlet; // Create commands and listen for events cmExit = new Command("Exit", Command.EXIT, 1); cmPrefs = new Command("Prefs", Command.SCREEN, 2); addCommand(cmExit); addCommand(cmPrefs); setCommandListener(t his); } /*-------------------------------------------------* Draw text *-------------------------------------------------*/ protected void paint(Graphics g) { // Clear the display g.setColor(255, 255, 255); // White pen g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(0, 0, 0); // Black pen // Use the user selected font preferences g.setFont(Font.getFont(face, style, size)); // Draw text at center of display 69
Mobile Programming (Private Version) g.drawString(text, getWidth() / 2, getHeight() / 2, Graphics.BASELINE | Graphics.HCENTER); } protected void setFace(int face) { this.face = face; } protected void setStyle(int style)
{ this.style = style; } protected void setSize(int size) { this.size = size; } public void setText(String text) { this.text = text; } public int getFace() { return face; } public int getStyle() { return style; } public int getSize() { return size; } public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDle t(); else if (c == cmPrefs) midlet.display.setCurrent(midlet.fmPrefs); } 70
/*-------------------------------------------------* PrefsForm.java * * Form that allows user to select font preferences *-------------------------------------------------*/ import javax.microedition.lcdui.*; public class PrefsForm extends Form implements CommandListener, ItemStateListener { private FontViewer midlet; // Main midlet private Command cmBack, // Back to canvas cmSave; // Save new font prefs protected ChoiceGroup cgFace, // Font face cgStyle, // style cgSize; // size protected TextField tfText; // Text string to display on canvas // (with the requested font prefs) private int face = 0, // Values for font attributes style = 0, // that are obtained from the choicegroups size = 0; private String text = null; // Value for text string from the textfield public PrefsForm(String title, FontViewer midlet) { // Call the form constructor super(title); // Save reference to MIDlet so we can // access the display manager class this.midlet = midlet; // Commands cmSave = new Command("Save", Command.SCREEN, 1); cmBack = new Command("Back", Command.BACK, 2); // Exclusive choice group for font face cgFace = new ChoiceGroup("Face Options", Choice.EXCLUSIVE); cgFace.append("System", null); cgFace.append("Monospace", 71
// Multiple choice group for font style cgStyle = new ChoiceGroup("Style Options", Choice.MULTIPLE); cgStyle.append("Plain", null); cgStyle.append("Bold", null); cgStyle.append("Italic", null); cgStyle.append("Underline d", null); // Exclusive choice group for font size cgSize = new ChoiceGroup("Size Options", Choice.EXCLUSIVE); cgSize.append("Small", null); cgSize.append("Medium", null); cgSize.append("Large", null); // Textfield for text to display on canvas tfText = new TextField("", "developerWorks", 20, TextField.ANY); // Create form contents and listen for events append(cgFace); append(cgStyle); append(cgSize); append(tfText); addCommand(cmSave) ; addCommand(cmBack); setCommandListener(this); setItemStateListener(this); } /*-------------------------------------------------* Command event handling *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { if (c == cmSave) { // Set the values in canvas class to those selected here 72
Mobile Programming (Private Version) midlet.cvFont.setFace(face); midlet.cvFont.setStyle(style); midlet.cvFont.setSize(size); // Make sure we aren't passing a null value midlet.cvFont.setText(tfText.ge tString() != null ? tfText.getString() : "developerWorks"); } // No specific check needed for "Back" command // Always return to the canvas at this point midlet.showCanvas(); } public void itemStateChanged(Item item) { if (item == cgFace) { switch (cgFace.getSelectedIndex()) { case 0: face = Font.FACE_SYSTEM; break; case 1: face = Font.FACE_MONOSPACE; break; case 2: face = Font.FACE_PROPORTIONAL; break; } } else if (item == cgStyle) { boolean[] b = new boolean[4]; cgStyle.getSelectedFlags(b); style = 0; // STYLE_PLAIN has a value of 0 // No need to check for b[0] // If bold selected if (b[1]) style = Font.STYLE_BOLD; // If italic selected if
73
Mobile Programming (Private Version) (b[2]) style |= Font.STYLE_ITALIC; // If underlined selected if (b[3]) style |= Font.STYLE_UNDERLINED; } else if (item == cgSize) { switch (cgSize.getSelectedIndex() ) { case 0: size = Font.SIZE_SMALL; break; case 1: size = Font.SIZE_MEDIUM; break; case 2: size = Font.SIZE_LARGE; break; } } else if (item == tfText) { text = tfText.getString(); } } }
h) V nh
Lp Graphics cung cp 1 phng thc dng v nh:
drawImage(Image img, int x, int y, int anchor)
Chng ta cng p dng tng bc khi v nh cng ging nh khi xut chui ra mn hnh. i vi c 2 th chng ta u phi bt u bng vic thit lp ta x, y cng nh im neo. Danh sch cc im neo cho vic hin th nh cng khng khc my so vi vic xut chui, tuy nhin khng ging vi vic xut chui th mt bc nh c mt im trung tm. V th VCENTER c thay th cho gia tr BASELINE khi lm vic vi nh Chiu ngang LEFT (Bn tri) HCENTER (im chnh gia theo chiu ngang) RIGHT (Bn phi) Chiu dc TOP (im trn) VCENTER (im chnh gia theo chiu dc) BOTTOM (Bn di 74
Trong cc phn trc, chng ta to ra cc ng dng MIDP cho vic trnh by mt tm nh c t mt ngun ti nguyn l mt tp tin. Loi nh ny khng cho php thay i, v v vy cn c bit vi tn l nh khng th thay i. i vi v d sau y, chng ta s to ra mt tm nh t nhng ng tp nham, chng ta s cp pht b nh cho tm nh, ly tham chiu n mt i tng Graphics, v chng ta s t v ni dung tm nh. Loi nh ny cn c bit vi mt ci tn l nh c th bin thay i c import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class DrawImage extends MIDlet { private Display display; // The display private ImageCanvas canvas; // Canvas public DrawImage() { display = Display.getDisplay(this); canvas = new ImageCanvas(this); } protected void startApp() { display.setCurrent( canvas ); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); 75
/*-------------------------------------------------* Class ImageCanvas * * Draw mutable image *-------------------------------------------------*/ class ImageCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private DrawImage midlet; private Image im = null; private String message = "developerWorks"; public ImageCanvas(DrawImage midlet) { this.midlet = midlet; // Create exit command and listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); try { // Create mutable image im = Image.createImage(100, 20); // Get graphics object to draw onto the image Graphics graphics = im.getGraphics(); // Specify a font face, style and size Font font = Font.getFont(Font.FACE_SYSTEM, Font.SIZE_MEDIUM); graphics.setFont(font);
Font.STYLE_PLAIN,
// Draw a filled (blue) rectangle, with rounded corners graphics.setColor(0, 0, 255); graphics.fillRoundRect(0,0, im.getWidth()-1, im.getHeight()-1, 20, 20); // Center text horizontally in the image. Draw text in white graphics.setColor(255, 255, 255); graphics.drawString(message, (im.getWidth() / 2) - (font.stringWidth(message) / 76
Mobile Programming (Private Version) 2), (im.getHeight() / 2) (font.getHeight() / 2), Graphics.TOP | Graphics.LEFT);
} catch (Exception e) { System.err.println("Error during image creation"); } } /*-------------------------------------------------* Draw mutable image *-------------------------------------------------*/ protected void paint(Graphics g) { // Clear the display g.setColor(255, 255, 255); g.fillRect(0, 0, getWidth(), getHeight()); // Center the image on the display if (im != null) g.drawImage(im, getWidth() / 2, getHeight() / 2, Graphics.VCENTER | Graphics.HCENTER); } public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); } }
int getClipWidth(); int getClipHeight(); translate() l mt phng thc c s dng c lin quan n h thng trc ta . Chng ta c th tnh tin h trc ta n mt im x, y khc. Mt s phng thc h tr cho vic tnh tin h trc ta
78
V.
X l s kin
V.3. V d
Di y l on m minh ha vic to ra v x l cc s kin Command, Item import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class EventProcessing extends MIDlet implements 80
Mobile Programming (Private Version) ItemStateListener, CommandListener { private Display display; // Reference to Display object for this MIDlet private Form fmMain; // Main Form private Command cmExit; // Command to exit the MIDlet private TextField tfText; // TextField component (item) public EventProcessing() { display = Display.getDisplay(this);
// Create the date and populate with current date tfText = new TextField("First Name:", "", 10, TextField.ANY); cmExit = new Command("Exit", Command.EXIT, 1); // Create the Form, add Command and DateField // listen for events from Command and DateField fmMain = new Form("Event Processing Example"); fmMain.addCommand(cmExit); fmMain.append(tfText); fmMain.setCommandListener(this); // Capture Command events (cmExit) fmMain.setItemStateListener(this); // Capture Item events (dfDate) } // Called by application manager to start the MIDlet. public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { System.out.println("Inside commandAction()"); if (c == cmExit) { 81
Mobile Programming (Private Version) destroyApp(false); notifyDestroyed(); } } public void itemStateChanged(Item item) { System.out.println("Inside itemStateChanged()"); } }
Record hin c cng nh khng lm thay i Record ID ca cc Record c to mi, v d: khi ta xa record id 3 khi thm mt record mi s c id l 4. Data l mt dy cc byte i din cho d liu cn lu. Tn c dung phn bit cc RecordStore trong b cc MIDlet (MIDlet suite). Cn ch khi nim MIDlet suite l tp cc MIDlet c chung khng gian tn (name space), c th chia s cng ti nguyn (nh RecordStore), cc bin tnh (static variable) trong cc lp v cc MIDlet ny s c ng gi trong cng mt file .jar khi trin khai. Nu ng dng ca bn ch c mt MIDlet th cc RecordStore c s dng cng phn bit ln nhau bng cc tn. Tn ca RecordStore c th di n 32 k t Unicode v l duy nht trong mt MIDlet suite.
83
ng lin th hin vic truy xut Record store do MIDlet to ra, ng nt t l Record store do MIDlet khc to ra. Trong MIDLET Suite One, MIDlet #1 v MIDlet #2 cng c th truy xut 4 Record store. MIDLET Suite One khng th truy xut Record store trong Suite Two. Trong MIDlet Suite One tn ca cc Record store l duy nhy, tuy nhin Record store trong cc MIDlet Suite khc nhau c th dng chung mt tn. Record Store cn c 2 thuc tnh l Version Number v Date/time Stamp, cc gi tr ny thay i khi thc hin thm, thay th hay xa mt record, ngoi ra cn c th dng c ch event handler (Listener) pht hin mi khi Record store b thay i. Version number l mt s integer, bit gi tr khi u bn cn gi hm getVersion() sau khi to mt Record store. Date/time Stamp l s long integer, l s miliseconds k t ngy 1 thng 1 nm 1970, bn c th bit c gi tr ny thng qua hm getLastModified().
LP: RecordStore Class: javax.microedition.rms.RecordStore M t Phng thc static RecordStore M mt Recordstore, c openRecordStore(String tham s to recordStoreName, boolean Record store nu n cha createIfNecessary) tn ti. void closeRecordStore() ng RecordStore. static void deleteRecordStore(String Xa RecordStore. recordStoreName) static String[] listRecordStores() Danh sch cc RecordStore trong int addRecord(byte[] data, int offset, MIDletmt record vo Thm suite. int numBytes) RecordStore. void setRecord(int recordId, byte[] t hoc thay th mt newData, int offset, int numBytes) record trong RecordStore. void deleteRecord(int recordId) Xa mt record trong byte[] getRecord(int recordId) RecordStore. cha record. Ly dy byte int getRecord(int recordId, byte[] Ly ni dung ca record vo buffer, int offset) dy byte. int getRecordSize(int recordId) Kch thc record. int getNextRecordID() Ly record id ca record int getNumRecords() milng cc record. S . long getLastModified() Thi gian thay i gn nht. int getVersion() Version ca RecordStore. String getName() Tn ca RecordStore. int getSize() Kch thc ca int getSizeAvailable() RecordStore. S byte trng cho RecordEnumeration enumerateRecords( RecordStore. Xy dng enumeration RecordFilter filter, RecordComparator dng duyt recordstore comparator, boolean keepUpdated) void addRecordListener (RecordListener listener) void removeRecordListener (RecordListener listener) Add a listener to detect record store Remove listener.
Chng ta hy cng xem qua 2 v d n gin ca vic c ghi record trong RecordStore.
Mobile Programming (Private Version) * ReadWrite.java * * Read and write to the record store. * * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class ReadWrite extends MIDlet { private RecordStore rs = null; static final String REC_STORE = "db_1"; public ReadWrite() { openRecStore(); // Create the record store // Write a few records and read them back writeRecord("J2ME and MIDP"); writeRecord("Wireless Technology"); readRecords(); closeRecStore(); // Close record store deleteRecStore(); // Remove the record store
} public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) 86
} public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); } } } public void writeRecord(String str) { byte[] rec = str.getBytes(); try { rs.addRecord(rec, 0, rec.length); } catch (Exception e) { db(e.toString()); } } public void readRecords() { try { byte[] recData = new byte[50]; int len; for (int i = 1; i <= rs.getNumRecords(); i++) { 87
len = rs.getRecord( i, recData, 0 ); System.out.println("Rec ord #" + i + ": " + new String(recData, 0, len)); System.out.println("-----------------------------"); } } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } } y l output ca v d 1:
// Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } Vi tham s true, hm s to mt RecordStore nu n cha tn ti. Trong hm WriteRecord, trc khi lu vo RecordStore, cn phi chuyn i kiu string thnh dy byte: byte[] rec = str.getBytes(); ... rs.addRecord(rec, 0, rec.length); Trong hm ReadRecord, chng ta cng cn c mt dy byte: byte[] recData = new byte[50]; ... len = rs.getRecord( i, recData, 0 ); Cn lu l trong v d trn do bit trc kch thc ca string nn khai bo dy byte va , trong thc t ta nn kim tra kch thc ca record khai bo dy byte cn thit trnh pht sinh li, do hm ReadRecord c th sa li nh sau: for (int i = 1; i <= rs.getNumRecords(); i++) { if (rs.getRecordSize(i) > recData.length) recData = new byte[rs.getRecordSize(i)]; len = rs.getRecord(i, recData, 0); System.out.println("Record #" + i + ": " + new String(recData, 0, len)); System.out.println("------------------------------"); } Nu ch cn c ghi nhng on text vo record, th v d trn l qu . Tuy nhin, thc t l ta cn lu nhng gi tr khc: String, int, boolean, v.v Trong v d 2 ny, chng trnh s s dng stream c v ghi record. Vic s dng stream gip chng ta linh ng v nng cao hiu qu ca vic c v ghi d liu vo RecordStore. V d 2: c v ghi s dng stream (ReadWriteStreams.java) /*-------------------------------------------------* ReadWriteStreams.java * * Use streams to read and write Java data types * to the record store. 89
* * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class ReadWriteStreams extends MIDlet { private RecordStore rs = null; // Record store static final String REC_STORE = "db_1"; // Name of record store public ReadWriteStreams() { openRecStore(); // Create the record store writeTestData(); // Write a series of records readStream(); // Read back the records closeRecStore(); // Close record store deleteRecStore(); // Remove the record store } public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { try { 90
} public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); } } } /*-------------------------------------------------* Create three arrays to write to record store *-------------------------------------------------*/ public void writeTestData() { String[] strings = {"Text 1", "Text 2"}; boolean[] booleans = {false, true}; int[] integers = {1 , 2}; writeStream(strings, booleans, integers); } /*-------------------------------------------------* Write to record store using streams. *-------------------------------------------------*/ public void writeStream(String[] sData, boolean[] bData,int[] iData) { try { // Write data into an internal byte array ByteArrayOutputStream strmBytes = new ByteArrayOutputStream(); // Write Java data types into the above byte array DataOutputStream strmDataType = new DataOutputStream(strmBytes); byte[] record; 91
for (int i = 0; i < sData.length; i++) { // Write Java data types strmDataType.writeUTF(sData[i] ); strmDataType.writeBoolean(bDat a[i]); strmDataType.writeInt(iData[i] ); // Clear any buffered data strmDataType.flush(); // Get stream data into byte array and write record record = strmBytes.toByteArray(); rs.addRecord(record, 0, record.length); // Toss any data in the internal array so writes // starts at beginning (of the internal array) strmBytes.reset(); } strmBytes.close(); strmDataType.close( ); } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Read from the record store using streams *-------------------------------------------------*/ public void readStream() { try { // Careful: Make sure this is big enough! // Better yet, test and reallocate if necessary byte[] recData = new byte[50]; // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData); // Read Java data types from the above byte array DataInputStream strmDataType = new DataInputStream(strmBytes); for (int i = 1; i <= rs.getNumRecords(); i++) { 92
// Get data into the byte array rs.getRecord(i, recData, 0); // Read back the data types System.out.println("Record #" + i); System.out.println("UTF: " + strmDataType.readUTF()); System.out.println("Boolean: " + strmDataType.readBoolean()); System.out.println("Int: " + strmDataType.readInt()); System.out.println("-------------------"); // Reset so read starts at beginning of array strmBytes.reset(); } strmBytes.close (); strmDataType.cl ose(); } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } }
93
D liu ghi vo record trong v d 2 gm: String[] strings = {"Text 1", "Text 2"}; boolean[] booleans = {false, true}; int[] integers = {1 , 2}; Hm WriteStream s ghi d liu vo RecordStore // Write data into an internal byte array ByteArrayOutputStream strmBytes = new ByteArrayOutputStream(); // Write Java data types into the above byte array DataOutputStream strmDataType = new DataOutputStream(strmBytes); byte[] record; for (int i = 0; i < sData.length; i++) { // Write Java data types strmDataType.writeUTF(sData [i]); strmDataType.writeBoolean(b Data[i]); strmDataType.writeInt(iData [i]); // Clear any buffered data strmDataType.flush (); // Get stream data into byte array and write record record = strmBytes.toByteArray(); rs.addRecord(record, 0, 94
Mobile Programming (Private Version) record.length); // Toss any data in the internal array so writes // starts at beginning (of the internal array) strmBytes.reset();
} Hm s dng hai stream l strmBytes l mt mng byte s ghi vo RecordSotre v strmDataType cha d liu. Nh vy qu trnh ghi d liu vo RecordStore c thc hin thng qua cc bc: Cp pht stream. Ghi d liu vo stream. Flush stream. Chuyn i stream data thnh mng byte. Ghi mng byte vo RecordStore. ng stream.
Vic c cc d liu t record n gin ch cn thay OutStream thnh InputStream: byte[] recData = new byte[50]; // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData); // Read Java data types from the above byte array DataInputStream strmDataType = new DataInputStream(strmBytes); for (int i = 1; i <= rs.getNumRecords(); i++) { // Get data into the byte array rs.getRecord(i, recData, 0); // Read back the data types System.out.println("Record #" + i); System.out.println("UTF: " + strmDataType.readUTF()); System.out.println("Boolean: " + strmDataType.readBoolean()); System.out.println("Int: " + strmDataType.readInt()); System.out.println("--------------------"); // Reset so read starts at beginning of array strmBytes.reset(); } y, chng ta khai bo mt mng byte recData (ging vi strmBytes), sau khi gi hm rs.getRecord(i, recData, 0); Chng ta c mng byte lc u chng trnh ghi vo record, sau dng
95
System.out.println("UTF: " + strmDataType.readUTF()); System.out.println("Boolean: " + strmDataType.readBoolean()); System.out.println("Int: " + strmDataType.readInt()); Lu : khi s dng DataOutputStream v DataInputStream, cn phi c v ghi theo ng th t, nu khng s khng ra kt qu mong mun.
96
Mobile Programming (Private Version) boolean hasPreviousElement() void keepUpdated(boolean keepUpdated) boolean isKeptUpdated() void rebuild() void reset() void destroy()
Trnh Cng Duy Kim tra enumeration c record trc t enumeration reindex sau khi co s thay i Kim tra enumeration c t ng reindex() To li index a enumeration v record u tin Gii phng ti nguyn c s dng bi enumeration
Do RecrdComparator l mt interface nn khi s dng cn phi implements n: public class Comparator implements RecordComparator { public int compare(byte[] rec1, byte[] rec2) { String str1 = new String(rec1), str2 = new String(rec2); int result = str1.compareTo(str2); if (result == 0) return RecordComparator.EQUIVALENT; else if (result < 0) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS } }
97
Sau ta s dng lp Comparator bng cch gn kt n vi RecordEnumeration: // Create a new comparator for sorting Comparator comp = new Comparator(); // Reference the comparator when creating the result set RecordEnumeration re = rs.enumerateRecords(null,comp,f alse); // Iterate through the sorted results while (re.hasNextElement()) { String str = new String(re.nextRecord()); } Enumeration s s dng hm compare trong class Comparator sp xp cc record trong RecordStore. RecordComparator Interface: javax.microedition.rms.RecordComparator Phng thc M t int compare(byte[] rec1, So snh quyt nh th t sp xp byte[] rec2) V d 3: chng trnh sp xp c bn /*-------------------------------------------------* SimpleSort.java * * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class SimpleSort extends MIDlet { private RecordStore rs = null; static final String REC_STORE = "db_1"; public SimpleSort() { openRecStore(); // Create the record store // Write a few records writeRecord("San d Wedge"); writeRecord("One Wood"); writeRecord("Put ter"); writeRecord("Fiv e Iron"); // Read back with enumerator, sorting the results readRecords(); closeRecStore(); // Close record store 98
Mobile Programming (Private Version) deleteRecStore(); // Remove the record store } public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp()
{ } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { 99
Mobile Programming (Private Version) db(e.toString()); } } } public void writeRecord(String str) { byte[] rec = str.getBytes(); try { rs.addRecord(rec, 0, rec.length); } catch (Exception e) { db(e.toString()); } }
public void readRecords() { try { if (rs.getNumRecords() > 0) { Comparator comp = new Comparator(); RecordEnumeration re = rs.enumerateRecords(null,comp, false); while (re.hasNextElement()) { String str = new String(re.nextRecord()); System.out.println(str); System.out.println("-----------------------------"); } } } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } 100
/*-------------------------------------------------| Comparator.java | | Compares two records to determine sort order *-------------------------------------------------*/ class Comparator implements RecordComparator { public int compare(byte[] rec1, byte[] rec2) { String str1 = new String(rec1), str2 = new String(rec2); int result = str1.compareTo(str2); if (result == 0) return RecordComparator.EQUIVALENT; else if (result < 0) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS; } } Trong on code trn trong hm readRecord(), khi to Enumeration ta tham chiu n i tng comp ca lp Comparator Comparator comp = new Comparator(); RecordEnumeration re = rs.enumerateRecords(null, comp, false); while (re.hasNextElement()) { ... } Khi enumerator to index cho RecordStore n s s dng hm compare() trn sp xp cc record. Output ca vi d 3:
V d trn ng trong trng hp d liu lu vo record l dng text, nu quay li v d 2 ta ghi nhiu kiu d liu vo trong mt record: 101
Mobile Programming (Private Version) // Write Java data types to stream strmDataType.writeUTF("Text 1"); strmDataType.writeBoolean(true); strmDataType.writeInt(1);
Cc kiu d liu trn s c lu vo mt stream dng binary. Sau cc stream ny s c chuyn thnh mng v a vo recordstore: // Get stream data into an array record = strmBytes.toByteArray(); // Write the array to a record rs.addRecord(record, 0, record.length); on code trong v d 3 s chy sai khi p dng vi kiu d liu binary. gii quyt, ta cn phi vit li hm compare() th c hin chc nng chuyn i chui byte v sp xp ng kiu d liu. Trong thc t, chng ta cn phi lu nhiu trng d liu trong mt record nh trong v d 2 (lu d liu kiu String, boolean, integer). Trong trng hp ny s c nhiu la chn sp xp cc record, v vic la chn ny ty thuc vo ng dng ca bn. Trong 2 v d sau y s thc thi interface RecordComparator sp xp record cha nhiu kiu d liu. Nhng v d ny s s dng cng d liu u vo, tuy nhin v d 4 s sp xp da vo kiu String, trong khi v d 5 s sp xp da vo kiu integer. y l d liu s lu vo recordstore: String[] pets = {"duke", "tiger", "spike", "beauregard"}; boolean[] dog = {true, false, true, true}; int[] rank = {3, 0, 1, 2}; Khi lu vo recordstore s c dng nh sau: Record #1 "duke" true 3 Record #2 "tiger" false 0 Record #3 "spike" true 1 Record #4 "beauregard" true 2 y l l do v d 3 khng p ng c yu cu, do d liu lu vo khng cn l dng text, v hm String.CompareTo() trn ni dung ca record khng th sp xp d liu theo mong mun. Do , bn cn phi ly ra t mi record trng d liu m bn mun sp xp. Trong v d 4 s ly kiu String u mi record, v d 5 s ly kiu integer cui mi record. V d 4: StringSort.java /*-------------------------------------------------102
Mobile Programming (Private Version) * StringSort.java * * Sort records that contain multiple Java * data types. Sort using String type. * * Uses: Streams, Enumeration, RecordComparator * * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class StringSort extends MIDlet { private RecordStore rs = null; // Record store static final String REC_STORE = "db_3"; // Name of record store public StringSort() { openRecStore(); // Create the record store writeTestData(); // Write a series of records readStream(); // Read back the records closeRecStore(); // Close record store deleteRecStore(); // Remove the record store
} public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } 103
Mobile Programming (Private Version) } public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); }
} } /*-------------------------------------------------* Create three arrays to write to record store *-------------------------------------------------*/ public void writeTestData() { String[] pets = {"duke", "tiger", "spike", "beauregard"}; boolean[] dog = {true, false, true, true}; int[] rank = {3, 0, 1, 2}; writeStream(pets, dog, rank); } /*-------------------------------------------------* Write to record store using streams. *-------------------------------------------------*/ public void writeStream(String[] sData, boolean[] bData,int[] iData) { try { // Write data into an internal byte array ByteArrayOutputStream strmBytes = new ByteArrayOutputStream(); // Write Java data types into the above byte array 104
DataOutputStream strmDataType = new DataOutputStream(strmBytes); byte[] record; for (int i = 0; i < sData.length; i++) { // Write Java data types strmDataType.writeUTF(sData[i]) ; strmDataType.writeBoolean(bData [i]); strmDataType.writeInt(iData[i]) ; // Clear any buffered data strmDataType.flush(); // Get stream data into byte array and write record record = strmBytes.toByteArray(); rs.addRecord(record, 0, record.length); // Toss any data in the internal array so writes // starts at beginning (of the internal array) strmBytes.reset(); } strmBytes.close(); strmDataType.close() ; } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Read from the record store using streams *-------------------------------------------------*/ public void readStream() { try { // Careful: Make sure this is big enough! // Better yet, test and reallocate if necessary byte[] recData = new byte[50]; // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData); // Read Java data types from the above byte array 105
DataInputStream strmDataType = new DataInputStream(strmBytes); if (rs.getNumRecords() > 0) { ComparatorString comp = new ComparatorString(); int i = 1; RecordEnumeration re = rs.enumerateRecords(null, comp, false); while (re.hasNextElement()) { // Get data into the byte array rs.getRecord(re.nextRecordId(), recData, 0); // Read back the data types System.out.println("Record #" + i++); System.out.println("Name: " + strmDataType.readUTF()); System.out.println("Dog: " + strmDataType.readBoolean()); System.out.println("Rank: " + strmDataType.readInt()); System.out .println("-------------------"); // Reset so read starts at beginning of array strmBytes.reset(); } comp.compareStringClose(); // Free enumerator re.destroy(); } strmBytes.close(); strmDataType.close() ; } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); 106
} /*-------------------------------------------------| Compares two strings to determine sort order | Each record passed in contains multiple Java data | types - use only the String data for sorting *-------------------------------------------------*/ class ComparatorString implements RecordComparator { private byte[] recData = new byte[10]; // Read from a specified byte array private ByteArrayInputStream strmBytes = null; // Read Java data types from the above byte array private DataInputStream strmDataType = null; public void compareStringClose() { try { if (strmBytes != null) strmBytes.close(); if (strmDataType != null) strmDataType.close(); } catch (Exception e) { } } public int compare(byte[] rec1, byte[] rec2) { String str1, str2; try { // If either record is larger than our buffer, reallocate int maxsize = Math.max(rec1.length, rec2.length); if (maxsize > recData.length) recData = new byte[maxsize]; // Read record #1 // Only need one read because the string to // sort on is the first "field" in the record strmBytes = new ByteArrayInputStream(rec1); strmDataType = new DataInputStream(strmBytes); str1 = strmDataType.readUTF(); // Read record #2 strmBytes = new ByteArrayInputStream(rec2); 107
Mobile Programming (Private Version) strmDataType = new DataInputStream(strmBytes); str2 = strmDataType.readUTF(); // Compare record #1 and #2 int result = str1.compareTo(str2); if (result == 0) return RecordComparator.EQUIVALENT; else if (result < 0) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS; } catch (Exception e) { return RecordComparator.EQUIVALENT; } } }
Trng d liu u tin trong cc record l kiu string, - dng lm tiu ch sp xp. Trc ht ta ly chui cn so snh trong dy byte bng hm readUTF() , ri dng compareTo() trong class String sp xp: // Read record #1 // Only need one read because the string to // sort on is the first "field" in the record . . . str1 = strmDataType.readUTF(); // Read record #2 . . . str2 = strmDataType.readUTF(); // Compare record #1 and #2 int result = str1.compareTo(str2);
108
Output ca v d 4:
V d 5:
/*-------------------------------------------------* IntSort.java * * Sort records that contain multiple Java * data types. Sort using integer type. * * Uses: Streams, Enumeration, RecordComparator * * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet .*; import javax.microedition.rms.*; public class IntSort extends MIDlet { private RecordStore rs = null; // Record store static final String REC_STORE = "db_4"; // Name of record store public IntSort() { openRecStore(); // Create the record store writeTestData(); // Write a series of records readStream(); // Read back the records closeRecStore(); // 109
Close record store deleteRecStore(); // Remove the record store } public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { 110
} /*-------------------------------------------------* Create three arrays to write to record store *-------------------------------------------------*/ public void writeTestData() { String[] pets = {"duke", "tiger", "spike", "beauregard"}; boolean[] dog = {true, false, true, true}; int[] rank = {3, 0, 1, 2}; writeStream(pets, dog, rank); } /*-------------------------------------------------* Write to record store using streams. *-------------------------------------------------*/ public void writeStream(String[] sData, boolean[] bData,int[] iData) { try { // Write data into an internal byte array ByteArrayOutputStream strmBytes = new ByteArrayOutputStream(); // Write Java data types into the above byte array DataOutputStream strmDataType = new DataOutputStream(strmBytes); byte[] record; for (int i = 0; i < sData.length; i++) { // Write Java data types strmDataType.writeUTF(sData[i]) ; strmDataType.writeBoolean(bData [i]); strmDataType.writeInt(iData[i]) ; // Clear any buffered data strmDataType.flush(); // Get stream data into byte array and write record record = strmBytes.toByteArray(); rs.addRecord(record, 0, record.length); // Toss any data in the internal array so writes // starts at beginning (of the internal array) strmBytes.reset(); } 111
} /*-------------------------------------------------* Read from the record store using streams *-------------------------------------------------*/ public void readStream() { try { // Careful: Make sure this is big enough! // Better yet, test and reallocate if necessary byte[] recData = new byte[50]; // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(recData); // Read Java data types from the above byte array DataInputStream strmDataType = new DataInputStream(strmBytes); if (rs.getNumRecords() > 0) { ComparatorInt comp = new ComparatorInt(); int i = 1; RecordEnumeration re = rs.enumerateRecords(null,comp, false); while (re.hasNextElement()) { // Get data into the byte array rs.getRecord(re.nextRecordId(), recData, 0); // Read back the data types System.out.println("Record #" + i++); System.out.println("Name: " + strmDataType.readUTF()); System.out.println("Dog: " + strmDataType.readBoolean()); System.out.println("Rank: " + strmDataType.readInt()); System.out.println("-------------------112
Mobile Programming (Private Version) "); // Reset so read starts at beginning of array strmBytes.reset(); } comp.compareIntClose(); // Free enumerator re.destroy(); } strmBytes.close( ); strmDataType.clo se(); } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } } /*-------------------------------------------------| Compares two integers to determine sort order | Each record passed in contains multiple Java data | types - use only the integer data for sorting *-------------------------------------------------*/ class ComparatorInt implements RecordComparator { private byte[] recData = new byte[10]; // Read from a specified byte array private ByteArrayInputStream strmBytes = null; // Read Java data types from the above byte array private DataInputStream strmDataType = null; public void compareIntClose() { try { if (strmBytes != null) strmBytes.close(); if (strmDataType != null)
113
} public int compare(byte[] rec1, byte[] rec2) { int x1, x2; try { // If either record is larger than our buffer, reallocate int maxsize = Math.max(rec1.length, rec2.length); if (maxsize > recData.length) recData = new byte[maxsize]; // Read record #1 // We want the integer from the record, which is // the last "field" thus we must read the String // and boolean to get to the integer strmBytes = new ByteArrayInputStream(rec1); strmDataType = new DataInputStream(strmBytes); strmDataType.readUTF(); strmDataType.readBoolean(); x1 = strmDataType.readInt(); // Here's our data // Read record #2 strmBytes = new ByteArrayInputStream(rec2); strmDataType = new DataInputStream(strmBytes); strmDataType.readUTF(); strmDataType.readBoolean(); x2 = strmDataType.readInt(); // Here's our data // Compare record #1 and #2 if (x1 == x2) return RecordComparator.EQUIVALENT; else if (x1 < x2) return RecordComparator.PRECEDES; else return RecordComparator.FOLLOWS; } catch (Exception e) { 114
Trong v d ny ta vn s dng d liu ca v d 4, tiu ch sp xp l theo kiu integer, do trc ht ta phi ly d liu trong dy byte. Tuy nhin,,c mt lu l do d liu ta cn ly nm cui cng trong dy byte do ra cn phi c theo th t, tc l phi c kiu String, boolean ri mi n integer:
// Read record #1 // W e want the integer from the record, which is // the last "field" thus we m ust read the String // and boolean to get to the integer ...
Output ca v d 5:
115
116
Trn y l mt class n gin thc thi interface RecordFilter. Class ny s c gn vi mt enumerator, v khi enumerator s dng hm matches() duyt ht recordstore ly ra nhng record cn tm: // Create a new search filter SearchFilter search = new SearchFilter("search text"); // Reference the filter when creating the result set RecordEnumeration re = rs.enumerateRecords(search,null,f alse); // If there is at least one record in result set, a match was found if (re.numRecords() > 0) // Do something RecordFilter Interface: javax.microedition.rms.RecordFilter Phng thc M t boolean matches(byte[] candidate) Tm kim record tha mn mt iu kin no Sau y ta s xem qua chng trnh tm kim n gin s dng interface RecordFilter: V d 6: /*-------------------------------------------------* SimpleSearch.java * * Display a Form and Textbox for searching records * Each record contains a String object. * * Uses: Enumeration, RecordFilter *-------------------------------------------------*/ import java.io.*; import javax.microedi tion.midlet.*; import javax.microedi tion.rms.*; import javax.microedi tion.lcdui.*; public class SimpleSearch extends MIDlet implements CommandListener { private Display display; // Reference to Display object private Form fmMain; // The main form private StringItem siMatch; // The matching text, if any private Command cmFind; // Command
Trang 117
to search record store private Command cmExit; // Command to insert items private TextField tfFind; // Search text as requested by user private RecordStore rs = null; // Record store static final String REC_STORE = "db_6"; // Name of record store public SimpleSearch() { display = Display.getDisplay(this); // Define textfield, stringItem and commands tfFind = new TextField("Find", "", 10, TextField.ANY); siMatch = new StringItem(null, null); cmExit = new Command("Exit", Command.EXIT, 1); cmFind = new Command("Find", Command.SCREEN, 2); // Create the form, add commands fmMain = new Form("Record Search"); fmMain.addCommand(cmEx it); fmMain.addCommand(cmFi nd); // Append textfield and stringItem fmMain.append(tfFi nd); fmMain.append(siMa tch); // Capture events fmMain.setCommandLis tener(this); //-------------------------------// Open and write to record store //-------------------------------openRecStore(); // Create the record store writeTestData(); // Write a series of records } public void destroyApp( boolean unconditional ) { closeRecStore(); // Close record store deleteRecStore(); } public void startApp() {
118
display.setCurrent(fmMain); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); } } } /*-------------------------------------------------* Create array of data to write into record store *-------------------------------------------------*/ public void writeTestData() { String[] golfClubs = { "Wedge...good from the sand trap", "Truong dai hoc khoa hoc tu nhien",
119
"Putter...only on the green", "Hoc mon LTUDM rat bo ich!"}; writeRecords(golfClubs); } /*-------------------------------------------------* Write to record store. *-------------------------------------------------*/ public void writeRecords(String[] sData) { byte[] record; try { // Only add the records once if (rs.getNumReco rds() > 0) return; for (int i = 0; i < sData.length; i++) { record = sData[i].getBytes(); rs.addRecord(record, 0, record.length); } } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Search using enumerator and record filter *-------------------------------------------------*/ private void searchRecordStore() { try { // Record store is not empty if (rs.getNumReco rds() > 0) { // Setup the search filter with the user requested text SearchFilter search = new SearchFilter(tfFind.getS tring()); RecordEnumeration re = rs.enumerateRecords(sear ch, null, false); 120
// A match was found using the filter if (re.numRecords() > 0) // Show match in the stringItem on the form siMatch.setText(new String(re.nextRecord())); re.destroy(); // Free enumerator } } catch (Exception e) { db(e.toString()); } } public void commandAction(Command c, Displayable s) { if (c == cmFind) { searchRecordStore(); } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } } /*-------------------------------------------------* Search for text within a record * Each record passed in contains only text (String) *-------------------------------------------------*/ class SearchFilter implements RecordFilter { private String searchText = null; public SearchFilter(String searchText) { // This is the text to search for this.searchText = searchText.toLowerCase(); }
121
public boolean matches(byte[] candidate) { String str = new String(candidate).toLowerCase(); // Look for a match if (searchText != null && str.indexOf(searchText) != -1) return true; else return false; } }
Sau khi vit class SearchFilter, ta to mt instance search, khi khai bo class RecordEnumeration s tham chiu n instance trn. Khi ch c nhng record tha mn iu kin (trong hm matches()) mi hin th trong result set: // Setup the search filter with the user requested text SearchFilter search = new SearchFilter(tfFind.getString()); RecordEnumeration re =rs.enumerateRecords(search,null,false); // A match was found using the filter if (re.numRecords() > 0) siMatch.setText(new String(re.nextRecord())); Output:
Tip theo y chng ta li xt thm mt v d v tm kim record. V d 7: /*-------------------------------------------------* SearchStreams.java * * Display a Form and Textbox for searching records * Each record contains multiple Java data types * (String, boolean and integer). Use the String * data for searching * * Uses: Enumeration, RecordFilter *-------------------------------------------------*/ import java.io.*; import javax.microedit ion.midlet.*; import javax.microedit ion.rms.*; import javax.microedit ion.lcdui.*; public class SearchStreams extends MIDlet implements CommandListener { private Display display; // Reference to Display object private Form fmMain; // The main form private StringItem siMatch; // The matching text, if any private Command cmFind; // Command to search record store private Command cmExit; // Command to insert items private TextField tfFind; // Search text private RecordStore rs = null; // Record store static final String REC_STORE = "db_7"; // Name of record store public SearchStreams() { display = Display.getDisplay(this); // Define textfield, stringItem and commands tfFind = new TextField("Find", "", 10, TextField.ANY); siMatch = new StringItem(null, null); cmExit = new Command("Exit", Command.EXIT, 1); cmFind = new Command("Find", Command.SCREEN, 2); // Create the form, add commands fmMain = 123
new Form("Record Search"); fmMain.addCommand(cmEx it); fmMain.addCommand(cmFi nd); // Append textfield and stringItem fmMain.append(tfFi nd); fmMain.append(siMa tch); // Capture events fmMain.setCommandLis tener(this); //-------------------------------// Open and write to record store //-------------------------------openRecStore(); // Create the record store writeTestData(); // Write a series of records } public void destroyApp( boolean unconditional ) { closeRecStore(); // Close record store deleteRecStore(); } public void startApp() { display.setCurrent(fmMain); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { 124
try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); } } } /*-------------------------------------------------* Create three arrays to write into record store *-------------------------------------------------*/ public void writeTestData() { String[] pets = {"duke - big, goofy golden retriever", "tiger - we found in a field", "spike - loves chasing car tires", "beauregard - barks at everything"}; boolean[] dog = {true, false, true, true}; int[] rank = {3, 0, 1, 2}; writeStream(pets, dog, rank); } /*-------------------------------------------------* Write to record store using streams. *-------------------------------------------------*/ public void writeStream(String[] sData, boolean[] bData,int[] iData) { try { // Only add the records once if
125
(rs.getNumRecor ds() > 0) return; // Write data into an internal byte array ByteArrayOutputStream strmBytes = new ByteArrayOutputStream( ); // Write Java data types into the above byte array DataOutputStream strmDataType = new DataOutputStream(st rmBytes); byte[] record; for (int i = 0; i < sData.length; i++) { // Write Java data types strmDataType.writeUTF (sData[i]); strmDataType.writeBoo lean(bData[i]); strmDataType.writeInt (iData[i]); // Clear any buffered data strmDataType. flush(); // Get stream data into byte array and write record record = strmBytes.toByteArray(); rs.addRecord(record, 0, record.length); // Toss any data in the internal array so writes // starts at beginning (of the internal array) strmBytes.reset(); } strmBytes.close(); strmDataType.close(); } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Search using enumerator and record filter *-------------------------------------------------*/ private void searchRecordStore() { try
126
{ // Record store is not empty if (rs.getNumReco rds() > 0) { // Setup the search filter with the user requested text SearchFilter search = new SearchFilter(tfFind.getS tring()); RecordEnumeration re = rs.enumerateRecords(sear ch, null, false); // A match was found using the filter if (re.numRecords() > 0) { // Read from the specified byte array ByteArrayInputStream strmBytes = new ByteArrayInputStream(re.nextRecord()); // Read Java data types from the above byte array DataInputStream strmDataType = new DataInputStream(strmBytes); // Show matching result in stringItem component on form siMatch.setText(strmDataType.readUT F()); search.searchFilterClose(); // Close record filter strmBytes.close(); // Close stream strmDataType.close(); // Close stream re.destroy(); // Free enumerator } } } catch (Exception e) { db(e.toString()); } } public void commandAction(Command c, Displayable s) { if (c == cmFind)
127
{ searchRecordStore(); } else if (c == cmExit) { dest royA pp(f alse ); noti fyDe stro yed( ); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ private void db(String str) { System.err.println("Msg: " + str); } } /*-------------------------------------------------* Search for text within a record * Each record passed in contains multiple Java data * types (String, boolean and integer) *-------------------------------------------------*/ class SearchFilter implements RecordFilter { private String searchText = null; // Read from a specified byte array private ByteArrayInputStream strmBytes = null; // Read Java data types from the above byte array private DataInputStream strmDataType = null; public SearchFilter(String searchText) { // This is the text to search for this.searchText = searchText.toLowerCase(); } // Cleanup public void searchFilterClose()
128
{ try { if (strmBytes != null) strmBytes.close(); if (strmDataType != null) strmDataType.close(); } catch (Exception e) { } } public boolean matches(byte[] candidate) { String str = null; try { strmBytes = new ByteArrayInputStream(candidate); strmDataType = new DataInputStream(strmBytes); // Although 3 pieces of data were written to // the record (String, boolean and integer) // we only need one read because the string to // search is the first "field" in the record str = strmDataType.readUTF().toLowerCas e(); } catch (Exception e) { return false; } // Look for a match if (str != null && str.indexOf(searchText) != -1) return true; else return false; } } Cng c chc nng tm kim nhng v d 7 khc v d 6 ch d liu lu vo record. v d ny d liu lu vo record di dng dy byte, v trong dy byte ny ta li lu nhiu trng d liu: strmDataType.writeUTF(sData[i] ); // Write Strings strmDataType.writeBoolean(bDat a[i]); // Write booleans strmDataType.writeInt(iData[i] ); // Write integers 129
Trong hm searchRecordStore() ta to mt b tm kim v enumerator. Phng thc matches() (ca class SearchFilter) s c gi bi enumerator v c p dng cho mi record trong RecordStore. c c ng d liu cn dng ta cn dng hai stream mt dng c dy byte trong record v mt dng c ng kiu d liu trong dy byte . strmBytes = new ByteArrayInputStream(candidate); strmDataType = new DataInputStream(strmBytes); str = strmDataType.readUTF().toLowerCase();
Sau chui ny s c so snh vi searchText:
if (str != null && str.indexOf(searchText) != -1) return true; else return false; Output:
130
void recordChanged(RecordStore recordStore, int recordId) void recordDeleted(RecordStore recordStore, int recordId)
c gi khi record b xa
V d 8: s dng RecordListener /*-------------------------------------------------* RmsListener.java * * Test the RMS listener methods * * No GUI interface, all output is to the console *-------------------------------------------------*/ import java.io.*; import javax.microedition.midlet.*; import javax.microedition.rms.*; public class RmsListener extends MIDlet { private RecordStore rs = null; static final String REC_STORE = "db_8"; public RmsListener() { // Open record store and add listener openRecStore (); rs.addRecordListener(new TestRecordListener()); // Initiate actions that will wake up the listener writeRecord("J2ME and MIDP"); updateRecord("MIDP and J2ME"); deleteRecord(); closeRecStore(); // Close record store deleteRecStore(); // Remove the record store } public void destroyApp( boolean unconditional ) { } public void startApp() { // There is no user
131
interface, go ahead and shutdown destroyApp(false); notifyDestroyed(); } public void pauseApp() { } public void openRecStore() { try { // Create record store if it does not exist rs = RecordStore.openRecordStore(REC_S TORE, true ); } catch (Exception e) { db(e.toString()); } } public void closeRecStore() { try { rs.closeRecordStore(); } catch (Exception e) { db(e.toString()); } } public void deleteRecStore() { if (RecordStore.listRecordStores() != null) { try { RecordStore.deleteRecordStore(REC_STORE); } catch (Exception e) { db(e.toString()); } } } public void writeRecord(String str) { byte[] rec = str.getBytes(); try
132
{ rs.addRecord(rec, 0, rec.length); } catch (Exception e) { db(e.toString()); } } public void updateRecord(String str) { try { rs.setRecord(1, str.getBytes(), 0, str.length()); } catch (Exception e) { db(e.toString()); } } public void deleteRecord() { try { rs.deleteRecord(1); } catch (Exception e) { db(e.toString()); } } /*-------------------------------------------------* Simple message to console for debug/errors * When used with Exceptions we should handle the * error in a more appropriate manner. *-------------------------------------------------*/ public void db(String str) { System.err.println("Msg: " + str); } } /*-------------------------------------------------* Listen for updates to the record store *-------------------------------------------------*/ class TestRecordListener implements RecordListener { public void recordAdded(RecordStore recordStore, int recordId) { try {
133
System.out.println("Record with ID#: " + recordId + "added to RecordStore: " + recordStore.getName()); } catch (Exception e) { System.err.println(e); } } public void recordDeleted(RecordStore recordStore, int recordId) { try { System.out.println("Record with ID#: " + recordId + "deleted from RecordStore: " + recordStore.getName()); } catch (Exception e) { System.err.println(e); } } public void recordChanged(RecordStore recordStore, int recordId) { try { System.out.println("Record with ID#: " + recordId + "changed in RecordStore: " + recordStore.getName()); } catch (Exception e) { System.err.println(e); } } } Output:
134
135
C mt class chnh l Connector v 7 interfaces c nh ngha trong GCF. T hnh v ta d dng nhn thy GCF h tr kt ni dng datagram(packet) v stream. Class Connector c dng m kt ni n mt ti nguyn no thng qua phng thc open c khai bo nh sau: Connector.Open("protocol:address ;parameters");
136
public static DataOutputStream openDataOutputStream(String name); public static InputStream openInputStream(String name); public static OutputStream openOutputStream(String name);
Di y l on code m kt ni thng qua stream // Create a ContentConnection String url = "http://www.corej2me.com" ContentConnection connection = (ContentConnection) Connector.open(url); // With the connection, open a stream InputStream iStrm = connection.openInputStream(); // ContentConnection includes a length method int length = (int) connection.getLengt h(); if (length != -1) { byte imageData[] = new byte[length]; // Read the data into an array iStrm.read(imageData); } Tuy nhin, ngoi class ContentConnection, ta cng c th m mt kt ni trc tip bng InputStream. Sau y l on code cho php ti v mt bc nh v sau to li bc nh : InputStream iStrm = (InputStream) Connector.openInputStream(url); Image img = null; try { ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); int ch; while ((ch = iStrm.read()) != -1) bStrm.write(ch); // Place into image array byte imageData[] = bStrm.toByteArray();
137
// Create the image from the byte array img = Image.createImage(imageData, 0, imageData.length); } finally { // Clean up if (iStrm != null) iStrm.close(); } Lu , trong on code trn do khng s dng class ContentConnection, nn ta s khng bit c kch thc ca d liu s ti v. khc phc vn ny, ngi ta s dng ByteArrayOutputStream lu d liu ti v. Di y l v d n gin, u tin MIDlet s download v hin th hnh nh ti v. MIDlet s d dng ByteArrayOutputStream cha d liu ti v: /*-------------------------------------------------* DownloadImage.java * * Download and view a png file *-------------------------------------------------*/ import javax.micr oedition.m idlet.*; import javax.micr oedition.l cdui.*; import javax.micr oedition.i o.*; import java.io.*; public class DownloadImage extends MIDlet implements CommandListener { priva te Displ ay displ ay; priva te
138
TextB ox tbMai n; priva te Form fmVie wPng; priva te Comma nd cmExi t; priva te Comma nd cmVie w; priva te Comma nd cmBac k; public DownloadImage() { display = Display.getDisplay(this); // Create the textbox, allow maximum of 50 characters tbMain = new TextBox("Enter url", "http://localhost/intel.p ng", 55, 0); // Create commands and add to textbox cmExit = new Command("Exit", Command.EXIT, 1); cmView = new Command("View", Command.SCREEN, 2); tbMain.addCommand(cmExit); tbMain.addCommand(cmView ); // Set up a listener for textbox tbMain.setC ommandListe ner(this);
139
// Create the form that will hold the image fmViewPng = new Form(""); // Create commands and add to form cmBack = new Command("Back", Command.BACK, 1); fmViewPng.addCommand(cmB ack); // Set up a listener for form fmViewPng.setCommandListener(this); } public void startApp() { display.setCurrent(tbMain); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } /*-------------------------------------------------* Process events *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { // If the Command button pressed was "Exit" if (c == cmExit) { destroyApp(false); notifyDestroyed(); } else if (c == cmView) { // Download image and place on the form try { Image im; if ((im = getImage(tbMain.getString())) != null) { ImageItem ii = new ImageItem(null, im, ImageItem.LAYOUT_DEFAULT, null); // If there is already an image, set (replace) it if (fmViewPng.size() != 0) fmViewPng.set(0, ii); else // Append
140
the image to the empty form fmViewPng.append( ii); } else fmViewPng.append("Unsuccessful download."); // Display the form with image display.setCurrent(fmViewPng); } catch (Exception e) { System.err.println("Msg: " + e.toString()); } } else if (c == cmBack) { display.setCurrent(tbMain); } } /*-------------------------------------------------* Open connection and download png into a byte array. *-------------------------------------------------*/ private Image getImage(String url) throws IOException { InputStream iStrm = (InputStream) Connector.openInputStream(url); Image im = null; try { ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); int ch; while ((ch = iStrm.read()) != -1) bStrm.write(ch); // Place into image array byte imageData[] = bStrm.toByteArray(); // Create the image from the byte array im = Image.createImage(imageData, 0, imageData.length); } finally { // Clean up if (iStrm != null) iStrm.close(); }
141
return (im == null ? null : im); } } Mt textbox s cho php nhp a ch URL
142
c t ca phin bn MIDP 1.0 ch h tr HTTP, trong khi phin bn hin ti MIDP 2.0 h tr HTTP v HTTPS, cung cp kh nng bo mt tt hn. Cc hm API c khai bo trong HttpConnection (cho HTTP) v trong HttpConnections (cho HTTP v HTTPS).
Request method nh ngha cch m d liu s c gi n server. C 3 phng thc c cung cp sn l GET, POST, HEADER. Khi s dng Get, d liu cn request s nm trong URL. Vi Post d liu gi t client s c phn thnh cc stream ring bit. Trong khi , Header s khng gi d liu yu cu ln server, thay vo header ch request nhng meta information v server. GET v POST l hai phng thc request kh ging nhau, tuy nhin do GET gi d liu thng qua URL nn s b gii hn, cn POST s dng nhng stream ring bit nn s khc phc c hn ch ny.
V d v vic m HTTP Connection thng qua GET String url = "http://www.corej2me.c om?size=large"; HttpConnection http =
143
null; http = (HttpConnection) Connector.open(url); http.setRequestMethod(HttpConnection.GET); Nhng Header field s cho php ta truyn cc tham s t client n server. Cc header field thng dng l If-Modified-Since, Accept, and User Agent. Bn c th t cc Field ny thng qua phng thc setRequestProperty(). Di y l v d dng setRequestProperty(), ch c nhng d liu thay i sau ngy 1 thng 1 nm 2005 mi c gi v t server: String url = "http://www.corej2me.com \somefile.txt"; HttpConnection http = null; http = (HttpConnection) Connector.open(url); http.setRequestMethod(HttpConnection.GET); // Set header field as key-value pair http.setRequestProperty("If -Modified-Since", "Sat, 1 Jan 2005 12:00:00 GMT"); Body cha ni dung m bn mun gi ln server. V d v s dng POST v gi d liu t client thng qua stream: String url = "http://www.corej2me.com", tmp = "test data here"; OutputStream ostrm = null; HttpConnection http = null; http = (HttpConnection) Connector.open(url); http.setRequestMethod(HttpConnection. POST); // Send client body ostrm = http.openOutputStream(); byte bytes[] = tmp.getBytes(); for(int i = 0; i < bytes.length; i++) { os.write(bytes[i]); } os.flush(); Sau khi nhn c v s l yu cu t pha client, server s ng gi v gi v pha client. Cng nh client request, server cng gm 3 phn sau: Status line Header Body
Status line s thng bo cho client kt qu ca request m client gi cho server. HTTP phn loi status line thnh cc nhm sau y: 1xx is informational 2xx is success 3xx is redirection
144
4xx is client error 5xx is server error Status line bao gm version ca HTTP trn server, status code, v on text i din cho status code. V d:
"H TTP /1 .1 200 O K " "H TTP /1 .1 400 B ad R equest" "H TTP /1 .1 500 Interna l S erver E rror"
Header. Khng ging nh header ca client, server c th gi data thng qua header. Sau y l nhng phng thc dng ly thng tin Header m server gi v: String getHeaderField(int n); //Get header field value looking up by index String getHeaderField(String name); //Get header field value looking up by name String getHeaderFieldKey(int n); //Get header field key using index Server c th tr v nhiu Header field. Trong trng hp ny, phng thc u tin s cho ly header field thng qua index ca n. Cn phng thc th hai ly ni dung header field da vo tn ca header field. Cn nu mun bit tn (key) ca header field, c th dng phng thc th 3 trn. Sau y l v d v 3 phng thc trn, trong trng hp server gi v chui "content-type=text/plain". Phng thc http.getHeaderField(0) http.getHeaderField("contenttype") http.getHeaderFieldKey(0) Gi tr tr v "text-plain" "text-plain" "content-type"
Body: Cng ging nh client, server gi hu ht nhng thng tin trong phn body cho client. Client dng input stream c kt qu tr v t server.
b) The HttpConnection API Nh cp trn, ta s s dng HttpConnection API thit lp kt ni trong MIDP. Di y l nhng API trong HttpConnection:
145
Phng thc long getDate() long getExpiration() String getFile() int getHeaderField(int n) String getHeaderField(String name) long getHeaderFieldDate(String name, long def) int getHeaderFieldInt(String name, int def) String getHeaderFieldKey(int n) String getHost() long getLastModified() String getPort() String getProtocol() String getQuery() String getRef() String getRequestMethod() String getRequestProperty(String key) int getResponseCode() String getResponseMessage() String getURL() void setRequestMethod(String method) void setRequestProperty(String key, String value)
M t Get header field date Gets header field expiration Gets filename from the URL Gets header field value looking up by index Gets header field value looking up by name Gets named field as a long (representing the date) Gets named field as an integer Gets header field key using index Gets host from the URL Gets last-modified field value Gets port from the URL Gets protocol from the URL Gets the query string (only valid with GET request) Gets the reference portion of URL Gets the current setting of the request method (GET, POST or HEAD) Gets the current setting of a request property Gets the response code (numeric value) Gets the response message (text value) Gets the entire URL Sets the request method (GET, POST or HEAD) Sets a request property (header information)
V d: Chng ta s to mt MIDlet s dng HttpConnection ti v v hin th ni dung ca file text. Qua v d bn s hiu cch client gi request v ly response ca server. MIDlet cng s dng mt s phng thc trong HttpConnection thu thp thng tin v server: port, content type .. . /*-------------------------------------------------* FileViewer.java *-------------------------------------------------*/ import javax.microedition.midlet.*; import javax.microedition.io.*; import javax.microedition.lcdui.*; import java.io.*;
146
public class FileViewer extends MIDlet implements CommandListener { private Display display; private Form fmMain; private Command cmExit; private Command cmView; private String url = "http://localhost/text.txt"; public FileViewer() { display = Display.getDisplay(this); // Create exitcommand cmExit = new Command("Exit", Command.EXIT, 1); cmView = new Command("View", Command.SCREEN, 2); // Create the form and add commands fmMain = new Form("File Viewer"); fmMain.addCommand(cmExit); fmMain.addCommand(cmView); fmMain.setCommandListener(this); } public void startApp() { display.setCurrent(fmMain); } /*-------------------------------------------------* Process events *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { // If the Command button pressed was "Exit" if (c == cmExit) { destroyApp(false); notifyDestroyed(); } else if (c == cmView) { // Download image and place on the form try { 147
String str; if ((str = readFile()) != null) { // Delete form contents for (int i = fmMain.size(); i > 0; i--) fmMain.delete(0); // Append downloaded string fmMain.append("" + str); } } catch (Exception e) { System.err.println("Msg: " + e.toString()); } } } /*-------------------------------------------------* Read file *-------------------------------------------------*/ private String readFile() throws IOException { HttpConnection http = null; InputStream iStrm = null; String str = null; try { // Create the connection http = (HttpConnection) Connector.open(url); //---------------// Client Request //---------------// 1) Send request method http.setRequestMethod( HttpConnection.GET); // 2) Send header information (this header is optional) http.setRequestProperty("User-Agent", "Profile/MIDP-1.0 Configuration/CLDC-1.0"); // 3) Send body/data - No data for this request //---------------// Server Response //---------------148
System.out.println("url: " + url); System.out.println("-------------------------"); // 1) Get status Line System.out.println("Msg: " + http.getResponseMessage()); System.out.println("Code: " + http.getResponseCode()); System.out.println("-------------------------"); // 2) Get header information if (http.getResponseCode() == HttpConnection.HTTP_OK) { System.out.println("key 0: " + http.getHeaderFieldKey(0)); System.out.println("key 1 : " + http.getHeaderFieldKey(1)); System.out.println("key 2: " + http.getHeaderFieldKey(2)); System.out.println( "------------------------"); System.out.println("value (field) 0: " + http.getHeaderField(0)); System.out.println( "value (field) 1: " + http.getHeaderField(1)); System.out.println("value (field) 2: " + http.getHeaderField(2)); System.out.println( "------------------------"); // 3) Get data (show the file contents) iStrm = http.openInputStream(); int length (int) http.getLength(); if (length != -1) { // Read data in one chunk byte serverData[] = new byte[length]; iStrm.read(serverData); str = new String(serverData); } else // Length not available... { ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); // Read data one character at a time int ch; while ((ch = iStrm.read()) != -1) bStrm.write(ch); str = new String(bStrm.toByteArray()); bStrm.close(); } 149
//----------------------- -----// Show connection information //----------------------- ----System.out.println("Host: " + http.getHost()); System.o ut.println("Port: " + http.getPort()); System.out.println( "Type: " + http.getType()); } } finally { // Clean up if (iStrm != null) iStrm.close(); if (http != null) http.close(); } return str; } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } Output
150
Console output
151
Trong hnh trn, ta thy phn kt qu c time zones l ICT, do ta truyn tham s zzz, nu chuyn thnh zzzz ly full text ca time zones th kt qu s thay i nh sau:
Gi Servlet Yu cu gi servlet s uc khai bo bn trong commandAction(), v s c thc hin khi button cmRqst c kch hot:
152
/*-------------------------------------------------* Call the servlet *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { if (c == cmRqst) { try { serverMsg = null; callServlet(); if (serverMsg != null) fmMain.append(serverMsg); } catch (Exception e) { System.err.println("Msg: " + e.toString()); } } else if (c == cmExit) { destroyApp(false); notifyDestroyed(); } }
Di y l on code cho phng thc callServlet(), ch rng request ca client s dng request m ethod l GET,:
/*-------------------------------------------------* Call the servlet *-------------------------------------------------*/ private void callServlet() throws IOException { HttpConnection http = null; InputStream iStrm = null; boolean ret = false; // Examples - Data is passed at the end of url for GET String url = "http://localhost:8080/j2me/dateformatservlet?format= MMMM.dd.yyyy+'-'+hh:mm+aa"; String url= "http://localhost:8080/j2me/dateformatservlet?format=yyyy.M M.dd+'at'+hh:mm:ss+zzz"; try { http = (HttpConnection) Connector.open(url); //----------------
153
// Client Request //---------------// 1) Send request method http.setRequestMethod(HttpConnection.GET); // 2) Send header information - none // 3) Send body/data - data is at the end of URL //---------------// Server Response //---------------iStrm = http.openInputStream(); // Three steps are processed in this method call ret = processServerResponse(ht tp, iStrm); } finally { // Clean up if (iStrm != null) iStrm.close(); if (http != null) http.close(); } // Process request failed, show alert if (ret == false) showAlert(errorMsg); } Code cho servlet, hu ht cc phng thc u c bit trong doPost(), bin format dng lu request t client, sau servlet s gi SimpleDateFormat to ra kt qu ph hp vi request: import import import import import import javax.servlet.*; import javax.servlet.http.*; java.io.*; java.util.Date; java.text.SimpleDateFormat; java.util.TimeZone; java.util.Locale;
public class DateFormatServlet extends HttpServlet { public void init(ServletConfig config) throws ServletException { super.init(config); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 154
doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String format = request.getParameter("format"); SimpleDateFormat simpleDate = new SimpleDateFormat(format); Date dt = new Date(); PrintWriter out = response.getWriter(); response.setContentType("text /html"); out.println(simpleDate.format(dt)); out.close(); } public String getServletInfo() { return "DateFormatServlet"; } } MIDlet nhn kt qu tr v t servlet, trc ht phi kim tra status line vi server v c kt tr v kt qu hay khng (HTTP_OK). Do khng c thng tin header nn s tin hnh ly kt qu t input stream: /*-------------------------------------------------* Process a response from a server *-------------------------------------------------*/ private boolean processServerResponse(HttpConnection http, InputStream iStrm) throws IOException { //Reset error message errorMsg = null; // 1) Get status Line if (http.getResponseCode() == HttpConnection.HTTP_OK) { // 2) Get header information - none // 3) Get body (data) int length = (int) http.getLength(); String str; if (length != -1) { byte servletData[] = new byte[length]; iStrm.read(servletData); str = new String(servletData); } else // Length not available... 155
{ ByteArrayOutputStream bStrm = new ByteArrayOutputStream(); int ch; while ((ch = iStrm.read()) != -1) bStrm.write(ch); str = new String(bStrm.toByteArray()); bStrm.close(); } // Save the server message serverMsg = str; return true; } else // Use message from the servlet errorMsg = new String( http.getResponseMessage()); return false; }
156
VIII.
VIII.1.
Ph lc
Tng s class v interface trong CLDC
Bng 1: Tng s class v interface trong CLDC Tn gi Miu t java.io java.lang java.util javax.microedition Qun l vic xut nhp ca h thng Cc lp Java c bn Cc lp h tr vic tnh thi gian, qun l tp hp v.v Qun l kt ni
Bng 2: Cc lp b sung trong MIDP 1.0 Tn gi Miu t javax.microedition.rms Qun l vic lu tr d liu javax.microedition.midlet Giao din trung gian gia Midlet v mi trng Midlet ang chy javax.microedition.io H tr HTTP javax.microedition.lcdui H tr giao din ngi dng
1 24
Bng 3: Tng s class v interface trong CDC Tn gi Miu t java.io java.lang java.lang.ref java.lang.reflect java.math java.net java.security java.security.cert java.text java.util Qun l vic xut nhp ca h thng Cc lp Java c bn Cc lp h tr b thu gom rc ca JVM H tr tnh nng reflection trong Java H tr cc php tnh trong ton hc H tr mng Cung cp cc tnh nng bo mt H tr cc chng thc trong bo mt Cung cp cc lp h tr thao tc trn text Cc lp h tr vic tnh thi gian, qun l tp hp v.v
157
7 9 10
VIII.2.
LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG
MIDP-1.0 MIDP-1.0
CLDC-1.0 CLDC-1.0
LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG
G5500 G5600 G7050 G7070 G7100 G7120 HB620T KE800 KE820 KE850 KE970 KF510 KF600 KF600d KF700 KF700-Orange KF750 KG195 KG200j KG220 KG245 KG290 KG300j KG320 KG800 KG920 KP230-V10a KP235-orange KP320 KT520 KU250 KU311 KU380 KU730 KU800 KU950 KU990 KU990-Orange L1100 L1150 L1400 L1400i L3100 L600V LX150 LX160 LX260 LX350 LX550
MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
0 0 0 0 0 0 0 0 0 0 4 2 4 1 0 0 0 2 3 0 0 0 3 0 2 0 1 1 0 0 4 1 1 1 3 2 1 2 1 0 2 1 0 2 0 3 0 6 8
159
LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG LG Mitsubishi Motorola
LX570 M4410 M6100 ME500c ME770 MG100a MG105 MG130 MG200 MG200c MG200d MG210 MG220 MG295 MG610c MG810C P7200 S5200 T5100 TU515 TU915 U250 U300 U310 U400 U450 U8100 U8100 UP.Link U8110 U8120 U8130 U8138 U8150 U8180 U8210 U8290 U830 U8330 U8360 U8380 U8500-V10 U8550 U880 U890 U900 U960 U970 M900 A-5B
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
MIDP-2.0 MIDP-2.0
CLDC-1.0 CLDC-1.1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 2 1 2 1 0 0 0 0 8 6 8 5 0 2 5 1 3 2 0 5 0 2 1 1 0 0 0 2
160
Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola
A1000 A1200 A1200r A630 A768 A780 A835 A845 A925. Accept-language:ru C261 C380 C381p C385 C390 C450 C550 C650 C975 C980M Canary E1 iTunes E1 ROKR E1000 E1000M E1060 E1070 E1070R E2 E380 E398 E398B E550 E770 E770v E790 E825 K1 K3 L2 L6 L6i L7 L71 L7i L9 M930 MOTORAZRmaxxV3
MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0
11 5 1 4 2 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
161
Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola
MOTORAZRV9 MOTOROKR E6 MOTOROKRE6 MPx220 MPx230 PEBL U6 RAZRV3x RAZRV3xv RAZRV3xx RAZRV6 RAZRV6v Sirius T720 U15 V1050 V1075 V180 V180ENS V185 V186 V186Q V188 V190 V195 V220 V220ENS V235 V280 V3 V300 V330 V360 V360i V360v V361 V365 V3i V3i_iTunes V3r V3t V3v V400 V500 V505 V525M V535
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 VSCL-1.1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 VSCL-1.1.0 MIDP-2.0 VSCL-1.1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0
1 0 1 13 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 4 2 0 1 0 0 0 0 0 0 6 0 0 2 1 0 0 0
162
Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Motorola Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia
V540 V545 V547 V550 V551 V551J V555 V600 V620 V635 V66M V80 V975 V980 V980M W490 W510 W510-orange Z3 2600c 2610 2626 2630 2650 2760 3100 3100b 3108 3110c 3120 3120b 3125 3155i 3200 3220 3230 3250 3300 3410 3500c 3510i 3555b 3560 3590 3595 3620 3650 3660 5100
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.1 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-1.0
CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-13 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0
MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.1 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0
CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0
0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 4 6 2 19 2 34 9 0 0 14 0 0 0 22 45 11 8 0 1 0 77 0 0 0 4 0 17 4 7
163
Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia
5140 5140i 5200 5300 5310XpressMusic 5500d 5610 XpressMusic 5610d-1 6010 6020 6021 6030 6030b 6060 6061 6070 6080 6085 6086 6100 6101 6102 6102i 6103 6108 6111 6125 6126 6131 6131NFC 6133 6136 6151 6165i 6170 6200 6220 6230 6230 UP.Browser 6230i 6233 6234 6235 6255 6260 6263 6265 6265i 6267
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-2.1 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1
MIDP-2.1
CLDC-1.1
20 2 2 0 2 1 0 0 4 30 8 21 1 1 1 6 1 1 0 49 9 1 1 0 1 0 0 0 0 0 0 0 0 0 10 2 4 238 0 114 0 0 2 5 2 0 0 0 1
164
Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia
6270 6275 6275i 6280 6282 6288 6300 6310i 6500c 6500s-1 6555 6555b 6600 6610 6610I 6620 6630 6650 6670 6680 6681 6682 6800 6820 6822 7200 7210 7250 7250I 7260 7270 7360 7370 7373 7390 7600 7610 7610 (3.0417.0) SymbianOS 7650 7710 8800 8800SI 8801 8910i 9300 9500 E50-1 E50-2
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.1 MIDP-2.1 MIDP-2.1 MIDP-2.1 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
0 0 3 2 0 1 1 8 1 1 0 1 35 11 26 5 38 0 6 32 8 2 2 3 1 3 14 9 9 3 5 5 0 0 0 3 13 0 4 3 1 0 0 0 3 2 0 1
165
Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia Nokia O2 O2 Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
E60-1 E61-1 E61i-1 E62-1 E65-1 E65-1 Orange E70-1 N-Gage N-GageQD N70 N70-1 N70-1 UP.Browser N71-1 N72 N73-1 N73-2 N75-3 N80-1 N90-1 N91 N91-1 N93-1 N93i-1 Xda 2mini Xda II SAMSUNG SGHX620 SGH-A412 SGH-A436 SGH-A437 SGH-A517 SGH-A701 SGH-A706 SGH-A707 SGH-A717 SGH-A727 SGH-A737 SGH-A801 SGH-B500 SGH-C100 SGH-C110 SGH-C130 SGH-C200 SGH-C207L SGH-C210 SGH-C218 SGH-C225 SGH-C230
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
0 1 0 1 0 0 1 3 4 1 70 0 0 1 1 0 0 0 8 0 0 0 0 0 0 0 2 1 0 0 2 1 2 0 0 1 0 0 3 0 0 0 0 0 0 0 0
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0
MIDP-2.0
CLDC-1.0
166
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-C240 SGH-C300 SGH-C417 SGH-C417 Profile SGH-D100 SGH-D307 SGH-D347 SGH-D357 SGH-D407 SGH-D410 SGH-D500
CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
0 0 0 1 0 4 2 2 2 0 16 0 5 0 4 19 17 0 0 0 4 3 5 6 0 1 12 0 3 0
MIDP-2.0 MIDP-1.0 SGH-D500C MIDP-2.0 MIDP-2.0 SGH-D500E MIDP-1.0 SGH-D510 MIDP-2.0 SGH-D520 MIDP-2.0 MIDP-2.0 SGH-D600 MIDP-1.0 MIDP-2.0 SGH-D600E MIDP-1.0 SGH-D720 MIDP-2.0 SGH-D730 MIDP-2.0 SGH-D780 MIDP-2.0 SGH-D800 MIDP-2.0 SGH-D807 MIDP-2.0 MIDP-2.0 SGH-D820 MIDP-1.0 SGH-D830 MIDP-2.0 SGH-D836 MIDP-2.0 SGH-D840 MIDP-2.0 MIDP-2.0 SGH-D900 MIDP-1.0 SGH-D900-ORANGE MIDP-2.0 MIDP-2.0 SGH-D900i MIDP-1.0 SGH-E100 MIDP-2.0 SGH-E200 MIDP-1.0 SGH-E210 MIDP-2.0 SGH-E217 MIDP-2.0 MIDP-2.0 SGH-E250 MIDP-1.0 MIDP-2.0 SGH-E250-ORANGE MIDP-1.0 SGH-E250-VODA MIDP-2.0 SGH-E300 SGH-E310
3 0 0 26 5 0 0 0
167
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-E315 SGH-E316 SGH-E317 SGH-E330 SGH-E330N SGH-E335 SGH-E338 SGH-E340 SGH-E350 SGH-E350E SGH-E360 SGH-E370 SGH-E380 SGH-E390 SGH-E420 SGH-E480 SGH-E490 SGH-E500 SGH-E530 SGH-E570 SGH-E590 SGH-E600 SGH-E610 SGH-E610C SGH-E620 SGH-E630 SGH-E635 SGH-E700 SGH-E700A SGH-E710 SGH-E715 SGH-E720 SGH-E720C SGH-E728 SGH-E730 SGH-E736 SGH-E738 SGH-E758 SGH-E760 SGH-E770
MIDP-2.0 MIDP-1.0
CLDC-1.0 CLDC-1.0
MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1
0 0 1 1 0 0 0 0 5 20 17 4 2 2 0 9 1 0 4 1 1 0 0 0 2 0 0 0 0 0 0 4 0 0 1 0 0 0 0 3
MIDP-2.0
CLDC-1.0
168
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-E780 SGH-E790 SGH-E800 SGH-E800N SGH-E810 SGH-E820 SGH-E840 SGH-E850 SGH-E860V SGH-E870 SGH-E880 SGH-E900 SGH-E950 SGH-F110 SGH-F330-TEN SGH-F400 SGH-F480 SGH-F480-Vodafone SGH-F490 SGH-F490-ORANGE SGH-F490-Vodafone SGH-F510/1.0 SGH-F700 SGH-F700-Vodafone SGH-G600 SGH-G800 SGH-I300 SGH-I320 SGH-i600 SGH-I607 SGH-i640V SGH-I700 SGH-i710 SGH-i780 SGH-i780ORANGE SGH-i900 SGH-J200 SGH-J600 SGH-J600E SGH-J620 SGH-J700 SGH-J700-ORANGE SGH-J750 SGH-J750BNGI4 SGH-L600
CLDC-1.1 CLDC-1.1
1 1 0 0 0 1 2 0 0 0 3 24 1 0 0 1 0 1 1 0 0 0 0 4 2 3 0 0 0 0 0 0 0 2 1 0 3 7 1 0 2 1 1 0 0
MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
169
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-L760 SGH-L760-Vodafone SGH-L770-Vodafone SGH-M110 SGH-M300 SGH-M600 SGH-P180-ORANGE SGH-P200-ORANGE SGH-P207 SGH-P220-ORANGE
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 SGH-P260-ORANGE MIDP-1.0 SGH-P300 MIDP-2.0 SGH-P310 MIDP-2.0 SGH-P400 SGH-P510 SGH-P520 MIDP-2.0 SGH-P730 SGH-P730C SGH-P735 SGH-P777 SGH-P910 MIDP-2.0 SGH-P920 MIDP-2.0 SGH-S105 SGH-S200 SGH-S300 SGH-S300M SGH-T209 MIDP-2.0 SGH-T219 MIDP-2.0 SGH-T309 SGH-T319 MIDP-2.0 SGH-T329 MIDP-2.0 SGH-T409 MIDP-2.0 SGH-T429 MIDP-2.0 SGH-T439 MIDP-2.0 SGH-T509 SGH-T509S SGH-T519 MIDP-2.0 SGH-T539 MIDP-2.0 SGH-T609 SGH-T619 MIDP-2.0 SGH-T629 MIDP-2.0 SGH-T629R MIDP-2.0 SGH-T639 MIDP-2.0 SGH-T719 SGH-T729 MIDP-2.0 MIDP-2.0 SGH-T809 MIDP-1.0 SGH-T819 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1
1 2 1 0 0 2 0 0 2 0 1 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0
CLDC-1.1
CLDC-1.1 CLDC-1.1
170
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-T999 SGH-U100 SGH-U600 SGH-U700 SGH-U700-Vodafone SGH-U900 SGH-U900-Vodafone SGH-X100 SGH-X105 SGH-X120 SGH-X140 SGH-X160 SGH-X166 SGH-X200 SGH-X210 SGH-X300 SGH-X400 SGH-X426 SGH-X426M SGH-X427M SGH-X430 SGH-X450 SGH-X460 SGH-X466 SGH-X475 SGH-X480 SGH-X480C SGH-X486 SGH-X488 SGH-X495 SGH-X497 SGH-X500 SGH-X507 SGH-X510 SGH-X520X SGH-X526 SGH-X530 SGH-X600 SGH-X620 SGH-X628 SGH-X630 SGH-X636 SGH-X640 SGH-X650 SGH-X660
1 0 14 4 1 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 1 3 2 0 0 0 0 0 0 0 0 0 3 1 13
MIDP-1.0
CLDC-1.0
MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1
171
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung
SGH-X670 SGH-X680 SGH-X700 SGH-X800 SGH-X808 SGH-X810 SGH-X820 SGH-Z107 SGH-Z110 SGH-Z130/1.0 SGH-Z140 SGH-Z150 SGH-Z170 SGH-Z230 SGH-Z240 SGH-Z300 SGH-Z300/1.0 SGH-Z308 SGH-Z310 SGH-Z360 SGH-Z370/1.0 SGH-Z400 SGH-Z400-Vodafone SGH-Z500 SGH-Z500/1.0 SGH-Z510/1.0 SGH-Z540 SGH-Z548 SGH-Z560 SGH-Z560-Vodafone SGH-Z630/1.0 SGH-Z720 SGH-Z720-Vodafone SGH-ZV10 SGH-ZV40-Vodafone SGH-ZV50-Vodafone SGH-ZV60-Vodafone SGH-ZX10 SGH-ZX20 SPH-A640 SPH-A660 SPH-A680 SPH-A700 SPH-A740 SPH-A800 SPH-A840 SPH-A860 SPH-A880
MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 SPRINTPCS-1.0 MIDP-1.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0
0 0 11 0 0 1 2 1 0 0 17 0 3 4 3 0 16 2 0 0 0 2 0 21 16 1 11 1 1 2 0 0 1 3 0 1 0 0 1 2 2 0 4 9 1 0 0 2
MIDP-2.0
CLDC-1.1
172
Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Samsung Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens
SPH-A900 SPH-A900P SPH-A920 SPH-A940 SPH-M300 SPH-M500 SPH-M510 SPH-M610 SPH-M620 Z105 A31 A65 AF51 AL21 AX72 AX75 C110 C55 C60 C65 C66 C6V C72 C75 C81 CF62 CF75 CFX65 CL75 CX65 CX65i CX6V CX70 CX70I CX75 CX7A CX7I CX7V E71 EF81 EL71 M50 M55 M55C M65 M6V M75 M81 MC60
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 SPRINTPCS-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 null MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 null CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0
26 5 7 5 1 4 0 3 1 0 1 1 0 0 0 0 0 2 0 42 1 0 5 20 0 0 4 0 0 48 0 0 58 0 36 0 1 0 0 14 1 0 2 0 14 0 16 0 3
173
Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens Siemens SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son
MC6C ME75 S55 S65 S66 S68 S6C S6V S75 SF65 ObigoInternetBrowser SK65 SK6R SL65 SL6C SL75 SP65 ST60 SX1 SXG75 SXG75 UP.Browser C702 C902 D750i F500i G700 G700c J300a J300i K123i K300a K300i K310i K320i K500c
0 7 3 43 0 0 0 2 3 0
MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-2.1 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
2 0 3 0 0 0 0 2 1 0 1 0 0 12 1 1 1 40 1 4 78 3 5 0
174
SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics
K500i K508i K510c K510i K530i K550i K600 K600i K608i K610i K660i K700i K750i K770i K790a K790i K800i K800iv K810i K850i M600i MODEL P1i P200 P800
MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
38 3 1 11 2 15 0 9 2 66 1 157 10 5 6 8 119 1 21 7 3 0 2 0
MIDP-1.0
CLDC-1.0
175
son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son
P900 P910 P910a P910i P990i S500i S700c S700i S710a T610 T616 T630 T637 T650i T68 V600i V660i V800 W200i W300i W380a W380i W550i W580i
MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-1.0 MIDP-2.0
CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.0 CLDC-1.1
24 1 3 28 3 4 2 25 5 12 1 25 4 1 0
MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0
0 0 9 28 15 0 0 0 9
176
SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics
W610i W660i W700i W710i W760i W800i W810i W830i W850i W880i W890i W910i W950i W960i Z1010 Z310a Z310i Z310iv Z320i Z500a Z500i Z520a Z520i Z530i Z550i
MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-2.1 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0
CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1 CLDC-1.1
6 8 3 0 0 6 41 0 16 15 4 3 7 1 13 0 2 0 0 11 0 0 2 7 5
177
son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son SonyErics son
MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-1.0 MIDP-2.0 MIDP-1.0 MIDP-2.0 MIDP-2.1 MIDP-2.1 MIDP-1.0 MIDP-2.0
1 3 2 3 1 0 1
VIII.3.
Tham kho:
http://java.sun.com/j2me/ http://www.cs.armstrong.edu/burge/pdf/huc/01_J2ME_Overview.pdf http://www.onjava.com/pub/a/onjava/2001/03/08/J2ME.html http://developers.sun.com/techtopics/mobility/midp/articles/wtoolkit/ CLDC Specification (JSR-30) http://www.jcp.org/jsr/detail/30.jsp CLDC Next Generation (JSR-139) http://www.jcp.org/jsr/detail/139.jsp MIDP Specification (JSR-37) http://www.jcp.org/jsr/detail/37.jsp Mobile Information Device Next Generation (JSR-118) http://www.jcp.org/jsr/detail/132.jsp PDA Profile Specification (JSR-75) http://www.jcp.org/jsr/detail/75.jsp CDC Specification (JSR-36) http://www.jcp.org/jsr/detail/36.jsp Foundation Profile Specification (JSR-46) http://www.jcp.org/jsr/detail/46.jsp Personal Profile Specification (JSR-62) http://www.jcp.org/jsr/detail/62.jsp RMI Profile Specification (JSR-66) http://www.jcp.org/jsr/detail/66.jsp Java Game Profile (JSR-134) http://www.jcp.org/jsr/detail/134.jsp J2ME Multimedia API Specification (JSR-135) http://www.jcp.org/jsr/detail/135.jsp J2ME White Papers KVM http://java.sun.com/products/cldc/wp Applications for Mobile Devices
178
http://java.sun.com/j2me/docs/pdf/midpwp.pdf J2ME Technologi es J2ME http://java.su n.com/j2me CLDC and KVM http://java.sun.com/products/cldc MIDP http://java.sun.com/products/midp MIDP for Palm OS http://java.sun.com/ CDC and CVM http://java.sun.com/products/cdc
J2ME Wireless Toolkit http://java.sun.com/products/j2mewtoolkit Metrowerks CodeWarrior for J2ME http://www.metrowerks.com/desktop/java Zucotto WHITEboard SDK http://www.zucotto.com/whiteboard/index.html RIM BlackBerry Java IDE http://developers.rim.net/tools/jde/index.shtml J2ME Developer Resources Java Developer Connection http://developer.java.sun.com/developer Java Wireless Developer Initiative http://java.sun.com/wireless Wireless Developer Network http://www.wirelessdevnet.com Micro Java Network http://www.microjava.com Java Mobile Community http://www.javamobile.org Java Enabled Phones and PDAs http://www.javamobiles.com KVM World http://www.kvmworld.com KVM-Interest Mailing List Archive http://archives.java.sun.com/kvm-interest.html XML Parsers for J2ME TinyXML Parser http://gibaradunn.s rac.org/tiny NanoXML Parser http://nanoxml.sourceforge.net 179