Buy Reviews
Powered by MaxBlogPress  

Archive for the ‘j2me’ Category

Java ME Canvas基礎應用程式的設計樣式

星期三, 九月 16th, 2009

這一篇是我在Design Pattern for Java ME Canvas based applications的中文翻譯,總共翻譯了15天,中間雖然夾雜著更改工作達人的佈景,不過仍算是久的了,網址在Java ME Canvas基礎應用程式的設計樣式
為了備份,並轉貼在此:

繼續閱讀 »

在S60第五版機器的MIDlet裡使用螢幕鍵盤

星期二, 九月 8th, 2009

這一篇是我在Using on-screen keypad in MIDlets in S60 5th Edition devices的中文翻譯,總共翻譯了15天,中間雖然夾雜著更改工作達人的佈景,不過仍算是久的了,網址在在S60第五版機器的MIDlet裡使用螢幕鍵盤
為了備份,並轉貼在此:

概論

S60第五版介紹了觸控螢幕以及640 x 360像素的較大螢幕,為了讓這個設備能較容易地執行舊版的MIDlet這裡有一個稱作螢幕鍵盤的MIDlet,它提供了MIDlet向後相容的功能,這個功能使用Canvas,但是最初不是為了觸控設備用的。

螢幕鍵盤從Canvas那裡用了部份的螢幕然後Canvas應用程式提供了可能使用鍵盤來產生鍵盤事件,指針事件仍然可以在Canvas區域運作除了在螢幕鍵盤的區域外都可以使用。

用法

螢幕鍵盤在每個安裝的MIDlet套件都會自動發動,但使用者可以從應用程式管理設定來改變螢幕鍵盤的顯示與否,可能的值 有』off』、』Navigation keys only』及』Game and navigation keys』,該設定是應用程式的設定所以也可以在每個安裝的MIDlet套件中來做不同設定,螢幕鍵盤的狀態是使用JAD的參數』Nokia- MIDlet-On-Screen-Keypad』來定義,他的可能值有』no』、』gameactions』及』navigationkeys』。

Nokia-MIDlet-On-Screen-Keypad: no
Nokia-MIDlet-On-Screen-Keypad: gameactions
Nokia-MIDlet-On-Screen-Keypad: navigationkeys

三個可能的螢幕鍵盤設定:

  • No keypad
  • Navigation keys keypad: game actions UP, DOWN, LEFT, RIGHT and FIRE
  • Game actions keypad: game actions UP, DOWN, LEFT, RIGHT, FIRE, GAME_A, GAME_B GAME_C and GAME_D

鍵盤還包括兩個功能鍵按鈕,注意,螢幕鍵盤沒有數字或字元鍵,只有上面列出的鍵,另外也要注意,假如應用程式已經定義螢幕鍵盤設定使用者就不能改變 它,假如這個設定沒有在JAD屬性中定義,使用者就可以更改,螢幕鍵盤設定對整個MIDlet套件皆有效,預設狀況下,假如鍵盤設定沒有定義,遊戲按鍵會 顯示。

下面的圖片顯示縱向的360 x 640螢幕的三個設定:有導航及遊戲鍵的螢幕鍵盤、有導航鍵的螢幕鍵盤及沒有螢幕鍵盤,螢幕的解析度(實際Canvas的繪圖區域)是:

  • 沒有螢幕鍵盤的全螢幕:360 x 640
  • 有導航鍵的螢幕鍵盤全螢幕:360 x 384
  • 有導航及遊戲鍵的螢幕鍵盤全螢幕:360 x 360
  • 沒有螢幕鍵盤的非全螢幕:360 x 487
  • 有導航鍵的螢幕鍵盤非全螢幕:360 x 292
  • 有導航及遊戲鍵的螢幕鍵盤非全螢幕:360 x 240

Image:Tube_minesweeper3.png

下圖顯示橫向640 x 360螢幕的三個設定:有導航及遊戲鍵的螢幕鍵盤、有導航鍵的螢幕鍵盤及沒有螢幕鍵盤,螢幕的解析度(實際Canvas的繪圖區域)是:

  • 沒有螢幕鍵盤的全螢幕: 640 x 360
  • 有導航鍵的螢幕鍵盤全螢幕: 372 x 360
  • 有導航及遊戲鍵的螢幕鍵盤全螢幕: 320 x 360
  • 沒有螢幕鍵盤的非全螢幕: 502 x 288
  • 有導航鍵的螢幕鍵盤非全螢幕: 298 x 288
  • 有導航及遊戲鍵的螢幕鍵盤非全螢幕: 251 x 288

Image:Tube_minesweeper4.png

上圖也顯示JAD的屬性』Nokia-MIDlet-Original-Display-Size』實際的運作情形。

在有鍵盤的設備裡的螢幕鍵盤

在有觸控螢幕及外加鍵盤的設備裡(像Nokia N97) 開啟鍵盤會增加螢幕鍵盤的一個新模式,當鍵盤開啟時,箭頭和遊戲鍵被移除,功能鍵的標籤會顯示在設備的右側或底部,其位置可以使用』Nokia- MIDlet-On-Screen-Softkeys-Position』這個系統屬性來改變,假如沒有使用這個屬性,預設功能鍵顯示在右側,注意,假 如』Nokia-MIDlet-On-Screen-Keypad』屬性有』no』的值,功能鍵就不會顯示。

Nokia-MIDlet-On-Screen-Softkeys-Position: bottom
Nokia-MIDlet-On-Screen-Softkeys-Position: right // default, this is used, if no property exists in the jad file

Canvas螢幕尺寸是580×360像素時,功能建在右側,當尺寸是480×360像素時,功能建在底部。

Image:N97_open.pngImage:N97_open_bottom.png

另見

TSJ000306 – MIDP:系統屬性

星期五, 九月 4th, 2009

這一篇是我在TSJ000306 – MIDP: System properties的中文翻譯,總共翻譯了15天,中間雖然夾雜著更改工作達人的佈景,不過仍算是久的了,網址在TSJ000306 – MIDP:系統屬性
為了備份,並轉貼在此:

ID TSJ000306 Creation date November 30, 2005; updated December 7, 2007
Platform Series 40 Platform, S60 Platform Devices
Category Java ME Subcategory MIDP
Keywords (APIs, classes, methods, functions):

說明

這份文件列出呼叫System.getProperty()方法所擷取出的系統屬性,關於本篇文章的系統屬性MIDlet會用來檢查設備支援的系統屬性。
假如系統屬性字串回傳』null』,這個功能沒有支援,有些系統屬性即使其相關的API有支援也可能傳回』null』,這是因為所列出的系統屬性包括列在 移動服務架構(JSR-177)的屬性,舉例40 3rd Edition, FP2系列的設備有SATSA-APDU套件(JSR-177),但是』microedition.satsa.apdu.version』系統屬性傳 回』null』。

CLDC 1.0 & 1.1、MIDP 1.0 & 2.0及JTWI 1.0

字串 說明
microedition.profiles 對於MIDP 2.0設備來說,這個屬性必須至少包含』MIDP-2.0『。
microedition.configuration 這個設備支援的J2ME組態,例如,』CLDC-1.0『。
microedition.locale 這台設備上本地設置的名稱,例如,』en-US『。
microedition.platform 主機平台或設備的名稱,在Nokia設備裡名稱包含有』Nokia』、設備型號及軟體版本等用』/』分隔的訊息,在』Nokia』跟型號間沒有空格也沒有』/』,這個平台字串的正式語法是:Nokia MODEL_NUMBER "/" SW_VERSION,例如,』Nokia6310i/4.42或Nokia3510i/p1.25『。
microedition.encoding 傳回平台的預設字元編碼,在Nokia設備裡這個值是』ISO-8859-1『。
microedition.commports 以逗號分隔的port列表會傳回:前綴的url字串用來打開串列埠連接。
microedition.hostname 定義在MIDP 2.0裡的javax.microedition.io.SocketConnection getLocalAddress()方法,假如可用的話傳回本地主機名稱。
microedition.jtwi.version 確認這個規格的相容設備及執行的版本,這個microedition.jtwi.version系統屬性的值必須是』1.0『。
microedition.msa.version 支援的MSA規格版本編號,可能的值有』1.0『或』1.0-SUBSET『來執行符合本規格。

套件展開

字串 說明
microedition.media.version 假如這個可選套件有支援,傳回一個版本字串,否則傳回』null『。
microedition.pim.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.m3g.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.location.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
bluetooth.api.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.io.file.FileConnection.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.global.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.chapi.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
microedition.sip.version 假如這個可選套件有支援,傳回版本字串,否則傳回』null『。
wireless.messaging.version 假如這個可選套件無線通訊API (JSR-120/205)有支援,傳回版本字串,否則傳回』null『。
microedition.amms.version 假如這個可選套件高級多媒體補充(JSR-234)有支援,傳回版本字串,否則傳回』null『。
microedition.m2g.version 假如這個可選套件J2ME的可縮放2D向量圖形API(JSR-226)有支援,傳回版本字串,否則傳回』null『。
microedition.payment.version 假如這個可選套件付款API (JSR-229)有支援,傳回版本字串,否則傳回』null『。
microedition.contactless.version 假如這個可選套件非接觸式通訊API (JSR-257)有支援,傳回版本字串,否則傳回』null『。
microedition.sensor.version 假如這個可選套件行動感測器API (JSR-256)有支援,傳回版本字串,否則傳回』null『。
obex.api.version 假如這個可選套件物件交換協定(OBEX)API(JSR-82)有支援,傳回版本字串,否則傳回』null『。

移動媒體API(JSR-135)

字串 說明
supports.mixing 查詢音頻混合是否支援,傳回的字串不是』true『就是』false『,假如混合有支援,下面的情況是true:

  • Manager.playTone至少同時有兩個聲調可以使用。
  • Manager.playTone可在同一時間,至少有一名演奏者播放音頻。
  • 至少同時可以有兩個演奏者播放音頻。
supports.audio.capture 查詢聲音擷取是否支援,傳回的字串不是』true『就是』false『。
supports.video.capture 查詢視頻擷取是否支援,傳回的字串不是』true『就是』false『。
supports.recording 查詢紀錄是否支援,傳回的字串不是』true『就是』false『。
audio.encodings 傳回指定支援的擷取音頻格式,每個格式會用一特定的語法指定,這些格式至少用一個空格來分隔,例如,』encoding=audio/wav『。
video.encodings 傳回指定支援擷取視頻格式的字串,每個格式會用一特定的語法指定,這些格式至少用一個空格來分隔,例如,』encoding=video/3gpp『。
video.snapshot.encodings VideoControlgetSnapshot方法支援的視頻快照格式,傳回指定支援擷取影像格式的字串,每個格式會用一特定的語法指定,這些格式至少用一個空格來分隔,例如,』encoding=png『。
streamable.contents 傳回可以串流的格式(例如,在整個內容被載入到記憶體前播放會開啟),假如可串流的格式不存在傳回』null『,目前沒有支援串流的格式。

無線通訊API(JSR-120, JSR-205)

字串 說明
wireless.messaging.sms.smsc SMS位址的表示使用下列BNF定義的msisdn項目來表示語法:
msisdn ::== "+" digits | digits
digit ::== "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |"8" | "9"
digits ::== digit | digit digits
wireless.messaging.mms.mmsc 傳回在設備上使用JSR-205的MMSC位址。

FileConnection API (JSR-75)

字串 說明
fileconn.dir.photos 這個指向整合式相機拍攝的照片或其他影像儲存的目錄,例如,』file:///c:/My files/Images/『。
fileconn.dir.videos 這跟前述的相同只是對應到視訊的部份,下載的視訊預設也存在這裡,例如,』file:///c:/My files/Video clips/『。
fileconn.dir.tones 鈴升級其他類似的音頻檔案存在這個目錄,例如,』file:///c:/My files/Tones/『。
fileconn.dir.memorycard 假如記憶體可使用的話它的根目錄,例如,』file:///d:/『。
fileconn.dir.private MIDlet套件的私人工作目錄,例如,』file:///c:/System/MIDlets/[1015f294]/scratch『。
fileconn.dir.photos.name 相片目錄的本地UI名稱,例如,』Images『。
fileconn.dir.videos.name 視訊目錄的本地UI名稱,例如,』Video clips『。
fileconn.dir.tones.name 聲音目錄的本地UI名稱,例如,』Sound clips『。
file.separator 檔案分隔字元,在Nokia設備:』/『。
fileconn.dir.memorycard.name 記憶卡目錄的本地UI名稱,例如,』Memory card『。

藍芽無線技術的Java™ API(JSR-82)

注意:Bluetooth API的LocalDevice.getProperty()方法應該用來擷取系統屬性,例如: LocalDevice.getProperty("bluetooth.connected.devices.max")

字串 說明
bluetooth.l2cap.receiveMTU.max 這指向整合式相機拍攝相片或其他影像儲存的目錄。
bluetooth.connected.devices.max 支援連結設備的最大數(包括停泊裝置),這個字串為十進制數字。
bluetooth.connected.inquiry 在連結時是否允許調查?有效值是』true『及』false『。
bluetooth.connected.page 在連結時是否允許傳呼?有效值是』true『及』false『。
bluetooth.connected.inquiry.scan 在連結時是否允許掃描?有效值是』true『及』false『。
bluetooth.connected.page.scan 在連結時甚否允許傳掃描?有效值是』true『及』false『。
bluetooth.master.switch 使否允許主/從開關?有效值是』true『及』false『。
bluetooth.sd.trans.max 並行服務發現交易的最大數,這個字串為十進制數字。
bluetooth.sd.attr.retrievable.max 每個服務紀錄擷取的最大服務屬性,這個字串為十進制數字。

可變動2D向量圖形API (JSR-226)

字串 說明
microedition.m2g.svg.version SVG的版本是由底層的實現所支援,例如,假如底層的SVG引擎符合W3C SVGT 1.1規格,傳回的字串為』1.1″,而SVGT 1.2則傳回』1.2″等等。
microedition.m2g.svg.baseProfile SVG的基底概貌是由底層的實現所支援,這是JSR-226 v1.0的』小』實現。

J2ME™的移動3D圖形API(JSR-184)

移動3D圖形API屬性可以使用Graphics3D.getProperties()方法來查詢,它會傳回屬性跟直的雜湊表,屬性』maxViewportWidth『及』maxViewportHeight『在M3G 1.1中加入,在M3G 1.0版這個MIDlet的這些屬性會傳回』null『,屬性』m3gRelease『沒有明定的規範,但它卻是特定執行的屬性。

範例值是來自S60 3rd版的設備,見JSR-184規格有更多關於3D圖形的資料,該規範可以在Forum Nokia – JSR-184找到。

字串 說明
supportAntialiasing 假如antialiasing有支援傳回』true『,否則傳回』false『,例如』false『。
supportTrueColor 假如真實色彩成現有支援傳回』true『,否則傳回』false『,例如,』false『。
supportDithering 假如混色有支援傳回』true『,否則傳回』false『,例如,』false『。
supportMipmapping 假如紋理映射假如有支援傳回』true』,否則傳回』false『,見JSR-184規範的Texture2D類別說明更多資訊,例如,』true『。
supportPerspectiveCorrection 假如透視校正有支援傳回』true『,否則傳回』false『,見JSR-184規範的PolygonMode類別說明有更多的資訊,例如,』true『。
supportLocalCameraLighting 假如local camera lightning有支援傳回』true』,否則傳回』false『,見JSR-184規範的PolygonMode類別說明有更多資訊,例如,』false『。
maxLights 傳回光源最大值,最小值是8,見JSR-184規範的Light類別的說明有更多資訊,例如,』8『。
maxViewportWidth 傳回視圖端口寬度的最大值,最小值需要256,見JSR-184規範的Graphics3D.setViewport()方法說明有更多資訊,例如,』null『。
maxViewportHeight 傳回視圖端口高度最大值,最小值需要256,見JSR-184規範的Graphics3D.setViewport()方法說明有更多資訊,例如,』null『。
maxViewportDimension 傳回{maxViewportWidth, maxViewportHeight}的最小值,最小值需要是256,例如,』1024『。
maxTextureDimension 傳回紋理圖像最大允許尺寸,這特定於每個執行,最小值需要是256,見JSR-184規範的Texture2D類別說明有更多資訊,例如,』256『。
m3gRelease 傳回JSR-184執行的釋出日期,例如,』04_wk49『。
maxSpriteCropDimension 傳回最大的裁切矩形尺寸,最小值需要是256,見JSR-184規範的Sprite3D類別說明有更多資訊,例如,』256『。
numTextureUnits 傳回設備支援的紋理單元數,最小值需要是1,見JSR-184規範的Appearance類別說明,例如,』2『。
maxTransformsPerVertex 傳回一個定義骨架數量限制的實做(骨架 = 在骨架群組中用來轉換的節點),這個實做在每一個頂點上有一個效應,最小值需要是2,見JSR-184規範的SkinnedMesh類別說明有更多資訊,例如,』4『。

Java™ 2 Platform, Micro Edition (JSR-177)的安全和信任服務API (SATSA)

字串 說明
microedition.smartcardslots 指示智慧卡插槽的名稱。傳回的值是用逗號分隔的智慧卡插槽的列表,這個列表可以用在Connector.open()字串來辨認指定的智慧卡插槽,一個典型的冷抽換SIM卡及可移動的熱插拔卡組態會是
0C,1H。
microedition.satsa.apdu.version 設備支援的SATSA-APDU API版本,例如,』1.0『。
microedition.satsa.crypto.version 設備支援的SATSA-CRYPTO API版本,例如,』1.0『。
microedition.satsa.pki.version 設備支援的SATSA-PKI API版本,例如,』1.0『。

J2ME™ (JSR-179)的Location API

字串 說明
fileconn.dir.landmarks 傳回儲存在檔案系統中的JSR-179地標的位置。
fileconn.dir.landmarks.name 傳回儲存地標的本地名稱。

高階多媒體補充API (JSR-234)

字串 說明
supports.mediacapabilities 傳回用一個空白分隔指定支援能力的字串(Unicode U+0020),至少會有一個可能的字串必須傳回,可能的值是:
music
audio3d
imageencoding
imagepostprocessing
camera
tuner
tuner.modulations 傳回新增的播放器指定支援的調諧器調製設定字串,傳回的調製設定用一個空白分隔(Unicode U+0020),假如沒有支援的調製,tuner.modulations傳回』null』,TunerControl指定下列的常數,但是支援的調製不 受限於這些:FM調頻音頻廣播的fm及AM音頻廣播的am
audio.samplerates 傳回用Hertz表示的指定音頻採樣率字串,用一個空白分隔(Unicode U+0020),也有其他可能支援的採樣率,但這些是建議,假如音頻輸出不支援,audio.samplerates傳回』null『。
audio3d.simultaneouslocations 傳回的字串指定SoundSource3D模組的最大數量,這個模組是在典型的網路遊戲狀況裡建議的應用程式在圖形顯示(2D或3D) 及回聲發生時同時啟用,SoundSource3D模組當它在PREFETCHED或STARTED狀態裡包含有一或一個以上的播放器時才會啟用,這個實 作不保證SoundSource3D的這個數值會在所有狀況下同時啟用;它對應用程式只是一個暗示,(它甚至有可能超過SoundSource3D這個數 值來同時啟用,但這也不能被保證),傳回的數值假定每個啟用的SoundSource3D都有一個播放器,並且這個播放器的內容型態是具有16kHz採樣 率及每個樣本16位元的單聲道線性WAV。
camera.orientations 傳回的字串指定設備的相機定位,這個字串含有每個設備的定位,並以一個空白來分隔(Unicode U+0020),定位的字串有格式化的設備名稱:沒有空白字元的定位,一個傳回的字串範例:』devcam0:outwards devcam1:inwards『,定位值可以是下面這樣:
inwards (當設備用自然的方式拿著時相機指向使用者),
outwards (當設備用自然的方式拿著時相機指向遠離使用者),
unknown (相機的指向是使用者自訂或是因為某些其他原因不能被知道),
假如沒有相機支援,camera.orientations傳回』null『,預設的相機(capture://video)會列在字串的第一個。
camera.resolutions 傳回的字串指定設備的相機傳感器尺寸,這個字串含有每個設備的傳感器尺寸,並以一個空白來分隔(Unicode U+0020),傳感器尺寸的字串有格式化的設備名稱:width x height沒有空白字元,
一個傳回字串的範例:』devcam0:1024x768 devcam1:640x480『,
假如沒有相機支援,camera.resolutions傳回』null『,預設的相機(capture://video)會列在字串第一個。

J2ME™ Web服務API (JSR-172)

字串 說明
xml.jaxp.subset.version 設備支援的JAXP Subset API版本,例如』1.0『。
xml.rpc.subset.version 設備支援的JAX-RPC Subset API版本,例如,』1.0『。

S60 3rd Edition, FP2系統屬性

字串 說明
com.nokia.mid.imei 設備的IMEI (國際移動設備識別碼),見IMEI in Wikipedia.
com.nokia.mid.imsi 儲存在SIM卡的IMSI (國際移動用戶識別碼),更多IMSI的資訊見IMSI in Wikipedia,注意存取此系統屬性受限於com.nokia.mid.mobinfo.IMSI的權限,預設這個權限只能製造商跟使用者域可以使用。
com.nokia.mid.networkid 網絡識別參數,像是network ID (CDMA的NID及GSM的MNC)以及網路簡稱,傳回的字串識別碼含有下列的格式:<network ID> (<network short name>)。
com.nokia.mid.networksignal 目前(GSM/CDMA)網路訊號強度,輸出的格式如下:<手機應該顯示的條狀數>( <訊號強度以dBm表示的>dBm)。
com.nokia.mid.networkavailability 網絡可用性,這個屬性傳回值包括』available』或』unavailable』。
com.nokia.mid.batterylevel 設備的電池充電水平,這個屬性值是用%表示的真實電池水平。
com.nokia.mid.countrycode 當前的網絡國家代碼。
com.nokia.mid.dateformat 使用者喜愛的設備日期格式字串,該字串根據Java 2, Standard Edition, version 1.4.1, java.text.SimpleDateFormat類別文件的格式化樣式。
com.nokia.mid.timeformat 使用者喜愛的設備時間格式字串,該字串根據定義在Java 2, Standard Edition, version 1.4.1, java.text.SimpleDateFormat類別文件的樣式。

其他

字串 說明
com.nokia.mid.dateformat 喜愛的日期格式字串樣式,其格式根據定義在Java™ 2 Platform, Standard Edition, version 1.4.1, java.text.SimpleDateFormat類別文件關於日期樣式的規則,只有SimpleDateFormat-定義過的樣式字元子集合可以 用在這個屬性裡。
com.nokia.mid.timeformat
(只在S40系列設備上)
喜愛的時間格式樣式字串,其格式根據定義在Java™ 2 Platform, Standard Edition, version 1.4.1, java.text.SimpleDateFormat類別文件關於時間樣式的規則,只有SimpleDateFormat-定義過的樣式字元子集合可以 用在這個屬性裡。
com.nokia.network.access
(只在S40系列的設備上)
傳回網路存取點型態,可能的值是:

  • pd — 數據封包,例如GPRS
  • csd — 電路交換數據,例如GSM CSD/HSCSD數據電話
  • bt_pan — 藍芽pan網絡
  • na — 不可用,這個時作不能決定型態
com.nokia.mid.imei
(只在S40 3rd Edition系列的設備上,不在Nokia 6270及Nokia 6111)
傳回設備的IMEI碼,注意:MIDlet必須被簽名為製造商或使用者域;否則該值為』null』。

藍芽API

星期二, 八月 18th, 2009

這一篇是我在Bluetooth API的中文翻譯,網址在藍芽API
為了備份,並轉貼在此:

Java ME (JSR-82)的藍芽API是一個可選的API,它允許開發人員使用藍芽無線科技來跟其他設備溝通以及使用OBEX協定來做物件交換(Object Exchange)。

這個API執行CLDC的藍牙協議棧:

Image:btooth_stack.jpg

它新增了兩個套件到Java ME:

  • javax.bluetooth
  • javax.obex (可選)

Bluetooth Chat HelloWorld範例。

連結

全螢幕的版權宣告畫面

星期二, 八月 18th, 2009

這一篇是我在SplashScreen Full Screen的中文翻譯,網址在全螢幕的版權宣告畫面
為了備份,並轉貼在此:

序言

這是一個很頻繁的需求當大部分的開發工作完成後通常每個客戶會需要一個版權宣告畫面,我甚至面臨過相同的狀況,然後我嘗試在我們的維基找這段程式碼,但是我找不到,所以我將給一個範例這樣我們就可以在這找到程式碼。

Image:Splash2.jpg

執行

要執行這個程式碼你必須照著下面做。

1) 建立一個繼承canvas的類別

2) 設定paint方法內的顏色。

     g.setColor(0xffffff);

3) 在paint()裡使用手機螢幕的寬高來繪製正方形

     g.fillRect(0, 0, width, height);

4) 建立圖像。

     sp=Image.createImage("/Splash.png");

5)在螢幕中心繪製圖像

     g.drawImage(sp, width / 2, height / 2, Graphics.VCENTER | Graphics.HCENTER);

另類限制

有些應用程式使用alert來顯示版權宣告畫面但那不能全螢幕顯示並且通常看起來不專業。

相關文章

Simple Splash screen implementation

Java ME的Hello World

星期二, 八月 18th, 2009

這一篇是我在Hello World in Java ME的中文翻譯,網址在Java ME的Hello World
為了備份,並轉貼在此:

假如我們想要學習一個新的語言,第一個程式總會是傳統的』Hello World!』

這一個程式會使用一個字串項目跟一個exit按鈕來建立一個新的表單。

要安裝Nokia設備所需要的開發工具,見文章開始使用Java ME安裝S60的Java ME開發工具使用MTJ建立第一支MIDlet

Image:helloworld.png

package com.example.helloworld;

import javax.microedition.midlet.MIDlet;
import javax.microedition.lcdui.*;

public class HelloWorldMidlet extends MIDlet implements CommandListener {

    public HelloWorldMidlet() {
    }
    // Display
    private Display display;
    // Main form
    private Form form;
    // For the message
    private StringItem stringItem;
    // For the exit command
    private Command exitCommand;

    public void commandAction(Command command, Displayable displayable) {
        if (displayable == form) {
            if (command == exitCommand) {
                exitMIDlet();
            }
        }
    }

    public void startApp() {
        // Create form
        stringItem = new StringItem("Hello", "Hello World!");
        form = new Form(null, new Item[] {stringItem});
        exitCommand = new Command("Exit", Command.EXIT, 1);
        form.addCommand(exitCommand);
        form.setCommandListener(this);

        // Get display for drawning
        display = Display.getDisplay(this);
        display.setCurrent(form);
    }

    // Your MIDlet should not call pauseApp(), only system will call this life-cycle method
    public void pauseApp() {
    }

    // Your MIDlet should not call destroyApp(), only system will call this life-cycle method    
    public void destroyApp(boolean unconditional) {
    }

    public void exitMIDlet() {
        display.setCurrent(null);
        notifyDestroyed();
    }

}

無線通訊API

星期二, 八月 18th, 2009

這一篇是我在Wireless Messaging API的中文翻譯,網址在無線通訊API
為了備份,並轉貼在此:

無線通訊API

From Forum Nokia Wiki

無線通訊API是Java ME的一個可選套件,它用來提供跨平台存取像是簡訊服務(SMS)、多媒體信息(MMS)以及推送功能(在接收的訊息上啟動MIDlet),WMA可以使用在CLDCMIDP之上。

這個類別是在套件javax.wireless.messaging之下。

WMA 1.0 (JSR-120)

這個規格(JSR 120)的1.0版允許開發人員以文字或二進位模式傳送及接收SMS,你可以傳送:

  • 一般的SMS文字訊息
  • 文字訊息定址到一個port號,例如另一個監聽此port的Java ME應用程式接收。
  • 二進制訊息定址到一個port號,例如另一個監聽此port的Java ME應用程式接收。

要傳送簡訊,你必須從Java ME使用一個協定sms://來使用通用網絡框架,WMA API提供下列的類別:

  • MessageConnection
  • MessageListener
  • TextMessage
  • BinaryMessage

你可以接受送到一個給定的port的簡訊,而不是從收件匣收一般的簡訊,限制的port也可使用,例如你不可以傳送WAP-推送的簡訊。

使用Nokia Connectivity Framework你可以在相同的PC上使用兩個或多個諾基亞模擬器測試傳送及接收簡訊,每個模擬器會有一個簡訊號碼定義在標題的區域。

JSR規格可以在http://www.jcp.org/en/jsr/detail?id=120找到。

WMA 2.0 (JSR-205)

WMA 2.0 (JSR-205)跟WMA 1.0 (JSR-120)的只要差別在於用於多媒體訊息的多段訊息的支援在這個版本被加入。

JS規格可以在http://www.jcp.org/en/jsr/detail?id=205找到。

參考

Java ME Location API(中文)

星期五, 八月 14th, 2009

這一篇是我在Java ME Location API的中文翻譯,網址在Java ME Location API(中文)
為了備份,並轉貼在此:

Location API是JSR 179用來尋找像經緯度的位置資訊。

這裡有一個程式碼範例:

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.location.*;

public class loctest extends MIDlet implements CommandListener
{
   private Display display;
   private Form form;
   private Command cmdExit,cmdOK;
   private StringItem si;         

   public loctest()
   {
      display = Display.getDisplay(this);
      form = new Form("Location Api test");
      cmdExit = new Command("Exit",Command.EXIT,5);
      cmdOK = new Command("OK",Command.OK,1);
      si = new StringItem("Geo Location", "Click OK");
      form.append(si);
      form.addCommand(cmdOK);
      form.addCommand(cmdExit);
      form.setCommandListener(this);
   }

   public void startApp()
   {
      display.setCurrent(form);
   }

   public void pauseApp()
   {
   }

   public void destroyApp(boolean flag)
   {
      notifyDestroyed();
   }

   public void commandAction(Command c, Displayable d)
   {
      if (c == cmdOK){
         Retriever ret = new Retriever(this);
         ret.start();
         } else if (c == cmdExit) {
            destroyApp(false);
      }
   }

   public void displayString(String string)
   {
      si.setText(string);
   }
}

class Retriever extends Thread
{
   private loctest midlet;
   public Retriever(loctest midlet)
   {
      this.midlet = midlet;
   }

   public void run()
   {
      try
      {
         checkLocation();
      }
      catch (Exception ex)
      {
         ex.printStackTrace();
         midlet.displayString(ex.toString());
      }
   }

   public void checkLocation() throws Exception
   {
      String string;
      Location l;
      LocationProvider lp;
      Coordinates c;

      Criteria cr= new Criteria();
      cr.setHorizontalAccuracy(500);

      lp= LocationProvider.getInstance(cr);
      l = lp.getLocation(60);

      c = l.getQualifiedCoordinates();
      if(c != null ) {
         // Use coordinate information 
         double lat = c.getLatitude();
         double lon = c.getLongitude();
         string = "\nLatitude : " + lat + "\nLongitude : " + lon;
       } else {
         string ="Location API failed";
       }
       midlet.displayString(string);
   }
}

值得一提的是,這個程式可以執行,但是因為我的Nokia 5800的衛星狀態常常說沒有訊號,所以我執行這隻程式時總是time out,太詭異了,要去問一下nokia 5800的好友看看!

觸控設備的Qwerty鍵盤畫布

星期五, 八月 14th, 2009

這一篇是我在A Canvas Qwerty Keyboard For Touch Devices的中文翻譯,網址在觸控設備的Qwerty鍵盤畫布
為了備份,並轉貼在此:

使用低階UI的鍵盤問題

虛擬鍵盤背後的意圖就是再沒有實體鍵盤的觸控設備上像是Nokia 5800 XpressMusic及Nokia 5530 XpressMusic手機在MIDlet(內建低階UI類別)裡有一個機制來輸入任何種類的文字。

當使用有實體鍵盤的設備來建立低階(Canvas或GameCanvas)應用程式時,能夠從所按的鍵來取得事件然後據此行動,每個鍵的ascii碼會傳到Canvas類別的keyPressed(int)方法裡。

文數鍵盤: 只有一個ascii碼會傳到keyPressed方法,這是因為每個鍵參考幾個字元的話就不能去確切知道使用者想要輸入什麼字元,通常ascii碼傳到這個方法裡的會是關於數值的。

Qwerty鍵盤:假如鍵盤是qwerty,就能夠獲取所有字元集的ascii碼,當像shift或數值模式被按下時設備就會負責改變字元集,所以正確的ascii碼可以傳到這個方法裡。

根據上述,在不同的諾基亞手機裡輸入文字可以用qwerty鍵盤來解決,而且在文數鍵盤及非實體鍵盤的手機裡可以存在。

有一種方法來解決的基本問題,它包含了結合低階及高階的顯示元件,當一個低階應用程式的指定區域建立,那麼這個想法就是援引一個TextBox元件、擷取使用者新增的文字然後再一次在低階元件裡顯示。

這個方法有下面的缺點。

  • 高階元件會佔用整個螢幕。
  • TextBox元件的外觀感覺是根據原生的外觀感覺而不是使用應用程式的外觀感覺而這可能會干擾使用者經驗,舉一個例應用程式的外觀感覺整個是藍的而原生元件是黑的。

在最新的S60 5th版本裡有一個附加元件不會佔用整個螢幕,它只需要在JAD檔裡增加一個屬性,你可以看看範例如何使用這個機制在下面的連結裡。 How to use pop-up TextBox in Java ME

總體設計考慮

可繪區域

Image:vkimage1.jpg
在S60 5th版本裡的Canvas的可繪區域可以用屬性Nokia-MIDlet-On-Screen-Keypad來改變,不同的可繪區域大小顯示在下表裡。
Nokia-MIDlet-On-Screen-Keypad

Value Portrait Landscape
*Default (gameactions & navigation keys) 360×360 320×360
navigationkeys 360×384 372×360
no 360×640 640×360

方向

有一個方法可以強迫鍵盤保持橫向,可以使用下面的屬性這樣作:

Nokia-MIDlet-App-Orientation

可能值:portrait 或 landscape

很重要的備註一下是在早期5800的軟體版本裡這個屬性沒有作用,這個問題已在早期的韌體版本中更正。 KIJ001169 – Fixed landscape mode cannot be set by using Java ME in Nokia 5800 XpressMusic
理想情況下在JAD或manifest檔裡使用這兩個屬性就可以有一個全螢幕的虛擬鍵盤(640×360):

  • Nokia-MIDlet-On-Screen-Keypad: no
  • Nokia-MIDlet-App-Orientation: landscape

鍵盤組成

Image:vkimage2.jpg

TOUCHKEYBOARD

這個類別用在觸控設備的虛擬鍵盤,鍵盤由TextFieldArea用來顯示輸入的文字,及一系列可用字元的按鈕來允許修改虛擬鍵的行為等組成。

所有按鈕繼承自宣告基本方法的Button類別,虛擬鍵盤包含三種不同的按鈕。

  1. MatrixButton:是顯示字元鍵盤的一部份,每個鍵有一個預覽然後當按鈕下時採取一個行動。
  2. PushButton:是單獨的按鈕,這些按鈕按下時不會顯示這個鍵的預覽,例如Ok、 backspace、shift,按鈕釋放時也會有行動會採取。
  3. ModeButton:是改變鍵盤一些行為的按鈕,像是字元集或是啟用指針,當按鈕按下時採取行動。

改變字元區域的外觀感覺

MatrixButton也稱為字元區域是由TiledLayer組成,TiledLayer包含三種不同的拼布,第一塊用在鍵盤的閒置狀態,第二 塊用在鍵盤被選擇的狀態而第三塊則用在鍵盤按下時在右邊預覽,在MatrixButton裡的字元集會直接繪在GameCanvas的Graphics 上,他們的Font及Color可以用方法setCharactersAreaFont(Font)setCharactersAreaFontColor(int)setCharactersAreaPreviewFontColor(int)來改變,這允許字元區域來調整不同的尺寸來跟應用程式有相同的外觀感覺。

改變TextFieldArea的外觀感覺

要根據應用程式所用的外觀感覺來改變TextFieldArea的外觀感覺,可以使用下面的方法setTextFieldFont(Font)setTextFieldBkgColor(int)setTextFieldBorderColor(int)setCursorColor(int)setTextFieldFontColor(int)

改變其餘按鈕的外觀感覺

虛擬鍵盤其餘的按鈕是PushButton及ModeButton,這些按鈕基本上是由Sprite物件組成,要改變另一個按鈕的外觀感覺需要修改 resources資料夾裡相關的圖檔,每個圖檔會參考一個私有常數,所以假如圖檔名稱改變也要確認這個私有常數有變更是很重要的。

限制字元的數目

要限制鍵盤裡輸入的字元數目可以使用函式 setMaxSize(int)

TEXTFIELDAREA

這個元件能夠保持並顯示文字,新增時指定一個尺寸並在元件整個生命週期裡都保留著,TextFieldArea類似S60原生文字輸入區域的行為這個行為可以在寫入一個文字訊息時見到。

改變外觀感覺

根據應用程式所使用的外觀感覺來改變是可能的。

要這樣做使用下面的方法setTextFieldFont(Font)、setTextFieldBkgColor(int)、setTextFieldBorderColor(int)、setCursorColor(int)、setTextFieldFontColor(int)

安排文字

這個部份負責擁有的文字安排,要辨別一個字可以藉著字元後的空白字原來做,假如這個字太長不能適合這行的其餘空間,它會被推到下一行,假如單獨的一 個字還是大於這個TextFieldArea的水平空間,這個字就會被分成幾段來適合這個部份的寬度,每次一個新的字元新增或刪除整個textArea必 須重組,這是因為文字可以在任何地方輸入的關係。

關於游標

游標標記新的字元可以新增的地方,當新增發生時,游標移到下個位置,游標的顏色可以使用方法setCursorColor(int)來修改或使用setCursorVisible(boolean)來隱藏,游標可以使用方法moveCursorLeft()moveCursorRight()移 到左邊或右邊,當游標到最後一行的最後一個位置時,輸入的下一個字元會讓這部份向下移一行所以游標始終可以見到並且在最後一行,同樣地假如游標移到這部份 的右上方並且其上還隱藏有幾行文字,那麼他會使得這部份向上移一行所以游標還是保持可見,在這幾個字裡游標控制TextFieldArea顯示的己行文 字。

繪製TextFieldArea

這個部份需要一個Graphics物件來繪製,要這樣做需要一個明確的呼叫方法paint(Graphics, int, int)來做,最後兩個參數表示這部份將繪製的Graphics的xy位置,這機制的最大好處是這部份的同一實體可以不同的Graphics及不同的位置來繪製,這個部份會將文字分成幾行,只有在螢幕的幾行文字會被繪製,其餘的會被忽略,游標所在的那一行始終保持可見。

新增新的字元及取得文字

TextFieldArea最大字元數可以使用方法setMaxSize(int)來確定,假如沒有指定這個值,就不會限制輸入的字元數,要在目前游標位置新增一個新的字元可以使用方法insertCharacterInCursorPosition(char)來做,在游標位置刪除一個字元可以使用方法deleteLastCharBeforeCursor()來做,要在任何時間設定文字可以使用方法 setText(String),這個方法將置換原有的文字然後將游標置於該行的結尾,要取得TextFieldArea現有的文字使用getText()方法。 要充分利用鍵盤在設備裡的文字安排功能,這個部份提供insertAscii(int)方 法,當Canvas或GameCanvas使用時,keyPressed方法提供按鈕按下的ascii碼,對於正常鍵盤手機來說這是按下數字的 ascii,對qwerty設備來說它會是按下鍵的值,假如shift或數值鍵被按下該設備會自動改變字元集,所以所收到的ascii是不同的並且對應於 所要的鍵,倒退鍵字元也會以ascii碼來收取,所以沒有必要用明確的方式來呼叫刪除的函式。

下載原始碼及執行檔

在這裡你可以找到完整的NetBeans專案包括原始碼及執行檔。 Image:TouchKeyboard.zip

下載JAVADOCS

這裡你可以找到API參考。 Image:Javadocs.zip

下載範例

下面你將發現使用這個元件的範例,你可以下載完整的範例。 Image:KeyBoardExample.zip

使用元件

下面的範例顯示如何使用TouchKeyboard及TextFieldArea類別,這個範例包含有兩個TextFieldAreas的一個主要 的canvas,負責檢測屬於這個應用程式的使用者點到那個區域,一旦應用程式偵測到TextFieldArea有被接觸它就會顯示虛擬鍵盤,當使用者在 虛擬鍵盤選擇OK按鈕時,輸入的文字會儲在一個變數裡,這個變數是根據資料(name或address)的然後這個值會傳到正確的 TextFieldArea,下一次鍵盤援引時,它會提供TextFieldArea所存的文字。

記住TextFieldArea會調整它所持有的文字成自己定義的大小,那就是為什麼在TouchKeyboard裡的文字跟這兩個TextFieldAreas裡的文字可能會不同。

下面這張圖片顯示兩張應用程式的螢幕快照

Image:vkimage3.jpg

Image:vkimage4.jpg

JAD & Manifest屬性

Nokia-MIDlet-On-Screen-Keypad: no
Nokia-MIDlet-App-Orientation: landscape

BigKeyboard.java

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import keyboard.TextFieldArea;
import keyboard.TouchKeyboard;
import keyboard.VirtualKeyboardListener;

public class BigKeyboard extends MIDlet
        implements VirtualKeyboardListener {

    public static BigKeyboard instance;     //static instance for the MIDlet

    private TouchKeyboard tkb;              //Virtual keyboard

    private Display display;
    private CanvasScreen canvas;            //Main application canvas

    int nameTransId;                        //transaction id to identify name

    int addressTransId;                     //transaction id to identify address

    public BigKeyboard() {
        instance = this;
        canvas = new CanvasScreen();
        display = Display.getDisplay(this);
    }

    public void startApp() {
        showCanvas();
    }

    /**
     * Shows the main application Canvas
     */
    public void showCanvas() {
        display.setCurrent(canvas);
    }

    /**
     * Shows the virtual keyboard in order to retrieve the name.
     * The name will be limited to 20 characters.
     * @param name
     */
    public void getName(String name) {
        if (tkb == null) {
            createKeyboard();            //create keyboard if it does not exists
        }
        //when keyboard is reseted, it returns a transactionId
        nameTransId = tkb.resetKeyBoard();
        tkb.setMaxSize(20);
        tkb.setText(name);
        display.setCurrent(tkb);
    }

    /**
     * Shows the virtual keyboard in order to retrieve the name.
     * The name will be limited to 80 characters.
     * @param address
     */
    public void getAddress(String address) {
        if (tkb == null) {              //create keyboard if it does not exists
            createKeyboard();
        }
        //when keyboard is reseted, it returns a transactionId
        addressTransId = tkb.resetKeyBoard();
        tkb.setMaxSize(80);
        tkb.setText(address);
        display.setCurrent(tkb);
    }

    /**
     * Creates a new instance of the keyboard and sets it with the right
     * customization parameters
     */
    private void createKeyboard() {
        tkb = new TouchKeyboard(TouchKeyboard.KEYBOARD_BIG, 0, 0, false);
        tkb.setTextFieldBkgColor(0xE0DBCA);
        tkb.setTextFieldBorderColor(0x040477);
        tkb.setTextFieldFontColor(0x0033CC);
        tkb.setBackgroundColor(0x44A51C);
        tkb.togglePointer();
        tkb.setVirtualKeyboardListener(this);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    /**
     * Method of the interface VirtualKeyboardListener.
     * This method is invoked when the OK button is pressed at the moment
     * the keyboard is displayed on the screen.
     * @param transactionId
     * @param text
     */
    public void okPressed(int transactionId, String text) {
        //use the transactionId to identify the purpose of the call
        if (transactionId == nameTransId) {
            canvas.setName(text);
        } else if (transactionId == addressTransId) {
            canvas.setAddress(text);
        }
        showCanvas();
    }
}

CanvasScreen.java

class CanvasScreen extends Canvas {

    /**
     * TextFieldArea containing the data of the name.  This textfield is only
     * to show information and so cursor should not be visible.
     */
    private TextFieldArea tfName;
    /**
     * TextFieldArea containing the data of the address. This textfield is only
     * to show information and so cursor should not be visible.
     */
    private TextFieldArea tfAddress;

    public CanvasScreen() {
        tfName = new TextFieldArea(200, 40);
        tfName.setCursorVisible(false);
        tfName.setTextFieldBorderColor(0xE024C1C);
        tfName.setTextFieldBkgColor(0xffffff);
        tfName.setTextFieldFontColor(0x0033CC);

        tfAddress = new TextFieldArea(200, 80);
        tfAddress.setCursorVisible(false);
        tfAddress.setTextFieldBorderColor(0xE024C1C);
        tfAddress.setTextFieldBkgColor(0xffffff);
        tfAddress.setTextFieldFontColor(0x0033CC);
    }

    /**
     * paints two rectangles in the screen
     * @param g
     */
    protected void paint(Graphics g) {
        g.setColor(68, 165, 28);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(255, 255, 255);
        g.drawString("Name (max 20 chars):", 10, 10, 0);
        tfName.paint(g, 10, 40);
        g.setColor(255, 255, 255);
        g.drawString("Address (max 80 chars):", 10, 100, 0);
        tfAddress.paint(g, 10, 140);
    }

    /**
     * sets the text of the TextFieldArea destined to name
     * @param name
     */
    public void setName(String name) {
        tfName.setText(name);
    }

    /**
     * sets the text of the TextFieldArea destined to address
     * @param address
     */
    public void setAddress(String address) {
        tfAddress.setText(address);
    }

    /**
     * Detects if user points the first or the second textFieldArea in the
     * touch device
     * @param x
     * @param y
     */
    protected void pointerPressed(int x, int y) {
        if (x > 10 && x < 210) {
            if ((y > 40) && (y < 80)) {       //Pointer hits the first textfield

                BigKeyboard.instance.getName(tfName.getText());
            } else if ((y > 140) && (y < 220)) {  //pointer hits the second textfield

                BigKeyboard.instance.getAddress(tfAddress.getText());
            }
        }
    }
}

Java ME platform SDK 3.0

星期四, 八月 13th, 2009

在Sun網站發現Java Wireless Toolkit 2.5.2這個工具已經變成了這個套件,而且這個套件內含在NetBeans 6.7中了,我還無法用eclipse+MTJ來做,電腦弄亂了,編譯不出來,今天重灌NetBeans 6.7才做出來,模擬器變得更炫了!

2009-08-13_111625

下午的時候重新用eclipse+MTJ也可以執行了!ya!