通過Push信息來自動(dòng)啟動(dòng)JAVA移動(dòng)應(yīng)用程序magic003 發(fā)表于 2006-05-29 03:43:43作者:magic003;Srijeeb Roy 來源:matrix;javaworld 評(píng)論數(shù):2 點(diǎn)擊數(shù):1,464 投票總得分:15 投票總?cè)舜?5 關(guān)鍵字:Push;JAVA;mobile 摘要:有些時(shí)候,對(duì)于一個(gè)企業(yè)級(jí)移動(dòng)應(yīng)用程序,從服務(wù)器將信息推向移動(dòng)設(shè)備,并且自動(dòng)激活一個(gè)已安裝的移動(dòng)應(yīng)用程序使其進(jìn)行必要的處理是非常重要的。由短信服務(wù)(SMS)作為推信息的協(xié)議,使用push注冊(cè)機(jī)制可以讓使用Mobile Information Device Profile 2.0的JAVA微小版本應(yīng)用程序擁有這一特征。添加MIDP 2.0的Push注冊(cè)特征到你的設(shè)備應(yīng)用程序中
摘 要 有些時(shí)候,對(duì)于一個(gè)企業(yè)級(jí)移動(dòng)應(yīng)用程序,從服務(wù)器將信息推向移動(dòng)設(shè)備,并且自動(dòng)激活一個(gè)已安裝的移動(dòng)應(yīng)用程序使其進(jìn)行必要的處理是非常重要的。由短信服務(wù)(SMS)作為推信息的協(xié)議,使用push注冊(cè)機(jī)制可以讓使用Mobile Information Device Profile 2.0的JAVA微小版本應(yīng)用程序擁有這一特征。 版權(quán)聲明:任何獲得Matrix授權(quán)的網(wǎng)站,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必保留以下作者信息和鏈接 作者:Srijeeb Roy ;magic003(作者的blog:http://blog./page/magic003) 原文:http://www./resource/article/44/44449_Push+JAVA+Mobile.html 關(guān)鍵字:Push;JAVA;mobile 移動(dòng)技術(shù)日漸流行。Java微小版本,或者叫Java ME(Sun的J2ME平臺(tái)的新名字),是最流行的開發(fā)移動(dòng)應(yīng)用程序的技術(shù)之一。使用Java ME,我們可以在使用JVM或KVM的手持設(shè)備上運(yùn)行多種無線應(yīng)用程序。 Connected Limited Device Configuration (CLDC)被包含在Java ME中,它是面向那些只擁有有限資源,使用KVM的設(shè)備。同樣,Mobile Information Device Profile(MIDP)也被包含在Java ME中,這是一個(gè)為了在手機(jī)上運(yùn)行應(yīng)用程序的基于CLDC的profile。運(yùn)行在移動(dòng)設(shè)備中的應(yīng)用程序模塊叫做MIDlet,是一個(gè)MIDP應(yīng)用程序。一個(gè)MIDlet主要是一組有序運(yùn)行的類,并且它們由運(yùn)行在移動(dòng)設(shè)備中的應(yīng)用程序管理軟件(AMS)所控制。 MIDP的最新版本(2.0)引入了很多新的特征來幫助開發(fā)者建立健壯的企業(yè)級(jí)應(yīng)用程序。其中一個(gè)比較重要的特征就是push注冊(cè)機(jī)制。在Java ME應(yīng)用程序中,我們有時(shí)候需要從服務(wù)器推數(shù)據(jù),并在設(shè)備上自動(dòng)啟動(dòng)一個(gè)移動(dòng)應(yīng)用程序,而不需要由用戶明確的啟動(dòng)設(shè)備。設(shè)想一種情形,當(dāng)一個(gè)針對(duì)他/她的名字的工作條款被建立時(shí),用戶必須能自動(dòng)得到通知,并且必須盡快地對(duì)此工作條款做出反應(yīng)。Java ME的push注冊(cè)機(jī)制能夠很容易地將信息推向一個(gè)Java ME應(yīng)用程序,并自動(dòng)啟動(dòng)該程序。在這篇文章中,我將向你展示如何將push注冊(cè)機(jī)制特征添加到你的移動(dòng)應(yīng)用程序中。 Push注冊(cè)機(jī)制的行為可以被描述為如下三個(gè)步驟: 1.MIDlet在移動(dòng)設(shè)備中注冊(cè)一個(gè)連同協(xié)議名稱的端口,如果任何信息到達(dá)指定的端口,并且使用相同的協(xié)議,那么AMS就將它轉(zhuǎn)交給MIDlet。注冊(cè)使用Java ME應(yīng)用程序描述符(JAD)文件靜態(tài)的完成。程序也能使用應(yīng)用程序內(nèi)置的API執(zhí)行動(dòng)態(tài)注冊(cè)。 2. 從服務(wù)器,信息被發(fā)送到特定的移動(dòng)設(shè)備,使用MIDlet應(yīng)用程序注冊(cè)監(jiān)聽的協(xié)議和端口。 3. 在信息被傳遞到移動(dòng)設(shè)備后,AMS調(diào)用注冊(cè)了監(jiān)聽此端口和協(xié)議的MIDlet應(yīng)用程序。一旦信息被轉(zhuǎn)交到MIDlet,那么處理信息就是此應(yīng)用程序的責(zé)任了。典型的,根據(jù)信息的信息的內(nèi)容,一個(gè)應(yīng)用程序會(huì)選擇打開一個(gè)屏幕,并允許用戶與服務(wù)器進(jìn)行一些事務(wù)。 在這篇文章的例子中,為了從服務(wù)器推信息,我們將使用一個(gè)GSM(移動(dòng)通信全球系統(tǒng))調(diào)制解調(diào)器。圖1較高層次地描述了我們將在此文中實(shí)現(xiàn)的場(chǎng)景。 ![]() 圖1. 從服務(wù)器push SMS消息到移動(dòng)設(shè)備的高層場(chǎng)景 在jad文件中,每一個(gè)push注冊(cè)條目都包含如下信息:MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>。 MIDlet-Push-<n>:push注冊(cè)屬性名稱。MIDlet套件中可以包含多條push注冊(cè)。<n>的數(shù)值從1開始,并且對(duì)于附加的條目必須使用連續(xù)的序數(shù)。第一個(gè)發(fā)現(xiàn)的缺失條目將中止列表。任何剩余的條目都會(huì)被忽略。 ConnectionURL:被Connector.open()使用的連接字符串。 MIDletClassName:負(fù)責(zé)連接的MIDlet。指定的MIDlet必須使用MIDlet-<n>記錄在描述文件或jar文件的manifest中登記過。 AllowedSender:一個(gè)指定的過濾器, 它將限制哪些發(fā)送者能夠能正當(dāng)啟動(dòng)請(qǐng)求的MIDlet。 MIDP 2.0 規(guī)范定義了數(shù)據(jù)報(bào)和socket帶內(nèi)連接的語法。當(dāng)其他規(guī)范為其他連接類型定義push 語義時(shí),它們必須既定義過濾器域期望的語法,又定義連接URL字符串的期望格式。 在jad文件中,一個(gè)push注冊(cè)的典型例子,使用socket連接,類似于如下: MIDlet-Push-1: socket://:77, com.sample.SampleApplication, *. 這個(gè)示例描述符條目在77端口處保存一個(gè)流套接字,并且允許所有的發(fā)送者。 從服務(wù)器推信息到移動(dòng)設(shè)別會(huì)帶來一些問題:如果我們想發(fā)送信息到一個(gè)在指定端口注冊(cè)了監(jiān)聽流套接字的特定設(shè)備,我們必須知道那個(gè)移動(dòng)電話的無線網(wǎng)絡(luò)IP。因?yàn)樵跓o線網(wǎng)絡(luò)中,很多手機(jī)不使用始終連接環(huán)境(有時(shí)候,提供商不支持設(shè)備中網(wǎng)絡(luò)中的靜態(tài)IP),發(fā)送信息到設(shè)備是有問題的。如果我們不知道設(shè)備的無線IP,我們將不能使用套接字連接從服務(wù)器發(fā)送信息到設(shè)備。 短信服務(wù)(SMS)在這種情況下派上了用場(chǎng)。使用SMS,我們指定目標(biāo)設(shè)備的電話號(hào)碼;因此在這種情況下,我們不需要知道設(shè)備的IP地址。但是,使用SMS作為觸發(fā)器同樣會(huì)帶來一些問題:因?yàn)镸IDP2.0規(guī)范只定義了針對(duì)數(shù)據(jù)報(bào)和套接字帶內(nèi)連接的語法,而沒有針對(duì)SMS連接的,所以不保證所有支持MIDP2.0的設(shè)備都能使用SMS作為觸發(fā)器來進(jìn)行push注冊(cè)。但無線消息API(WMA1.1)-一個(gè)在MIDP上能支持SMS的的可選包-現(xiàn)在得到很多移動(dòng)設(shè)備的支持,所以有更大的可能性,SMS作為push注冊(cè)機(jī)制的觸發(fā)器將得到很多設(shè)備的支持。對(duì)于這篇文章,我使用Nokia 6600移動(dòng)電話,它是支持SMS作為push注冊(cè)機(jī)制的觸發(fā)器的。 另外,從服務(wù)器發(fā)送一條SMS消息到設(shè)備不是簡(jiǎn)單直接的,因?yàn)橛泻芏嗤緩酱嬖?。SMS服務(wù)提供商提供API(或者暴露服務(wù)URL),通過這些API你能從你的服務(wù)器端應(yīng)用程序發(fā)送消息到你指定的移動(dòng)電話上。但這種方法依賴于SMS服務(wù)提供商和它特殊的計(jì)劃??蛇x的方式是使用一個(gè)GSM調(diào)制解調(diào)器,這樣你需要使GSM調(diào)制解調(diào)器與你的服務(wù)器端應(yīng)用程序進(jìn)行交互。在這篇文章中,我將使用一個(gè)開源的產(chǎn)品,SMSLib for Java V1.0(原名jSMSEngine),它能使GSM調(diào)制解調(diào)器與你的Java服務(wù)器端程序進(jìn)行交互。 另一個(gè)在此需要注意的要點(diǎn)是一條簡(jiǎn)單的SMS消息將不會(huì)激活MIDlet。我們必須發(fā)送SMS消息到MIDlet注冊(cè)監(jiān)聽的特定的端口。因此被用來發(fā)送SMS消息的軟件(或SMS服務(wù)提供商)必須能夠?qū)⑺l(fā)送到設(shè)備指定的端口。SMSLib for Java v1.0 支持這一功能。 當(dāng)我們使用GSM調(diào)制解調(diào)器方案,我們必須了解GSM調(diào)制解調(diào)器將在內(nèi)部使用SIM(訂戶識(shí)別模塊)卡來發(fā)送SMS消息。SIM卡依賴于某個(gè)移動(dòng)服務(wù)提供商。因此每條SMS短信將帶來與從常規(guī)GSM移動(dòng)電話發(fā)送消息同樣的花費(fèi)。正相反,對(duì)于一個(gè)企業(yè)級(jí)應(yīng)用(依賴于服務(wù)計(jì)劃),通過提供商的SMS網(wǎng)關(guān)發(fā)送批量SMS消息會(huì)被證實(shí)更節(jié)省開銷。但是,如果應(yīng)用程序不需要發(fā)送大量SMS消息來出發(fā)MIDlet,那么GSM調(diào)制解調(diào)器方案會(huì)是有效的開銷,并能從移動(dòng)服務(wù)提供商那里取消特殊的批量SMS服務(wù)依賴。 雖然我建議為了近期的產(chǎn)品使用購(gòu)買一個(gè)單獨(dú)的GSM調(diào)制解調(diào)器,但是測(cè)試此行為不要求夠買。通常地,很多GSM移動(dòng)電話模型帶有一個(gè)內(nèi)置的GSM調(diào)制解調(diào)器。那些移動(dòng)模型中的任何一個(gè)都能夠作為GSM調(diào)制解調(diào)器,來代替單獨(dú)的調(diào)制解調(diào)器。在這篇文章中,我使用另外一個(gè)Nokia 6600移動(dòng)電話,而不是一個(gè)單獨(dú)的GSM調(diào)制解調(diào)器,因?yàn)镹okia 6600有一個(gè)內(nèi)置的GSM調(diào)制解調(diào)器。 現(xiàn)在,讓我們開發(fā)一個(gè)實(shí)例程序,是我們能夠從一個(gè)Java服務(wù)器端應(yīng)用程序發(fā)送一條SMS消息到一個(gè)移動(dòng)電話的指定端口,并自動(dòng)啟動(dòng)移動(dòng)設(shè)備中的一個(gè)MIDlet。 使用push注冊(cè)特征開發(fā)客戶端MIDlet 為了開發(fā)客戶端,我們使用Sun Java Wireless Toolkit(原名為J2ME Wireless Toolkit)。我使用版本2.2。這個(gè)產(chǎn)品是免費(fèi)的,可以從Sun的網(wǎng)站下載。為了安裝和運(yùn)行此工具包,你必須在你的機(jī)器上裝有J2SE 1.4.2_02或更新的版本。 我使用Windows 2000 Professional 操作系統(tǒng)。 安裝Sun的工具包后,按照如下描述的步驟: 1.從開始菜單打開KToolBar:選擇程序,然后J2ME Wireless Toolkit 2.2,然后KToolbar。將會(huì)打開一個(gè)應(yīng)用程序窗口,如圖2所以。 ![]() 圖2. 打開KToolbar 2.現(xiàn)在,在剛才打開的窗口中點(diǎn)擊新建工程圖標(biāo)。會(huì)打開一個(gè)彈出窗口;在那里你可以指定工程名稱和MIDlet類名。在工程名稱中輸入MySamplePushRegistryProject,在MIDlet類名中輸入com.sample.MySamplePushRegistry。 ![]() 圖3. 新建一個(gè)工程 3.在步驟2后,會(huì)自動(dòng)出現(xiàn)另一個(gè)彈出窗口,它將允許你設(shè)定項(xiàng)目的其他設(shè)置。確保你在API 選擇標(biāo)簽中。在此標(biāo)簽中,從目標(biāo)平臺(tái)下拉菜單中選擇JTWI(如果還沒有選擇)。同樣確保CLDC 1.0單選按鈕被選中。不要鉤選Mobile Media API多選框(因?yàn)椴粫?huì)使用任何跟多媒體有關(guān)的API)。請(qǐng)參考圖4。 ![]() 圖4. 設(shè)置API首選項(xiàng) 4.現(xiàn)在進(jìn)入push注冊(cè)標(biāo)簽。點(diǎn)擊添加按鈕。將會(huì)出現(xiàn)一個(gè)彈出窗口。在連接URL域中輸入sms://:50001,在類域中輸入com.sample.MySamplePushRegistry,在允許發(fā)送者域中輸入*。請(qǐng)參考圖5。 ![]() 圖5 設(shè)置push注冊(cè)的屬性 5.在步驟4后,一個(gè)條目將會(huì)被加入到父窗口中。如圖6所示。 ![]() 圖6. 設(shè)置push注冊(cè)的屬性(續(xù)) 6.現(xiàn)在進(jìn)入許可標(biāo)簽。單擊添加按鈕。從許可樹中選擇javax/microedtion/io/Connector/sms并單擊OK。重復(fù)相同 的步驟來添加許可javax/wireless/messaging/sms/receive 和 javax/microedtion/io/PushRegistry。 7.在步驟6后,三項(xiàng)許可將被添加到應(yīng)用程序中。如圖7所示。 ![]() 圖7. 添加許可 8.現(xiàn)在進(jìn)入用戶定義標(biāo)簽。這里,我們添加用戶定義的變量,這將包含SMS端口。從我們的程序,我們查閱此用戶定義變量來讀取SMS端口。在此標(biāo)簽中,單擊添加按鈕。打開一個(gè)彈出窗口。輸入SMS-Port作為屬性名稱。選擇OK。出現(xiàn)了最初的彈出的窗口。輸入50001作為SMS-Port的值。如圖8所示。 ![]() 圖8. 添加定制屬性SMS-Port 9.現(xiàn)在,在設(shè)置窗口中單擊OK。這個(gè)動(dòng)作將帶回到KToolbar。 10.在步驟9后,如果你觀察由以上步驟產(chǎn)生的jad文件,C:/WTK22/apps/MySamplePushRegistryProject/bin/MySamplePushRegistryProject.jad(假設(shè)J2ME Wireless Toolkit 2.2被裝在目錄C:/WTK22中),你會(huì)找到在前面步驟中設(shè)定的完整配置。所有條目中最重要的一個(gè)如下:MIDlet-Push-1: sms://:50001, com.smaple.MySamplePushRegistry, *. 此條目確保你的應(yīng)用程序監(jiān)聽50001端口上的SMS消息。 現(xiàn)在,讓我們著眼于MIDlet應(yīng)用程序的代碼。這里,我僅僅提供MIDlet的一部分代碼片斷。 請(qǐng)看資源來下載在此應(yīng)用程序中使用的所有代碼。 public class MySamplePushRegistry extends MIDlet 在這個(gè)片斷中,如下要點(diǎn)值得注意:類MySamplePushRegistry集成了MIDlet。這個(gè)類實(shí)現(xiàn)了CommandListener,Runnable和MessageListener接口。在MIDlet的startApp()方法中,我們使用getAppProperty()方法得到SMS-Port屬性的值。我們也使用Generic Connection Framework(GCF)創(chuàng)建了一個(gè)連接來監(jiān)聽SMS消息。GCF的Connector類的open()方法創(chuàng)建了SMS連接。如果一個(gè)消息到達(dá)了,notifyIncomingMessage()方法會(huì)被調(diào)用,它會(huì)創(chuàng)建和啟動(dòng)一個(gè)線程(如果還沒有被創(chuàng)建)。在線程的run()方法中,程序等待一條消息(smsconn.receive())。當(dāng)消息被接受到,我們得到原始的消息并在Alert類中設(shè)定消息。在現(xiàn)實(shí)生活的應(yīng)用程序中,用戶通常打開一個(gè)屏幕來處理消息。 一旦你的代碼準(zhǔn)備好了,使用KToolbar中的創(chuàng)建圖標(biāo)來創(chuàng)建它。在編譯和無錯(cuò)誤預(yù)驗(yàn)證創(chuàng)建之后,你需要把應(yīng)用程序打包成一個(gè)JAR。為了完成這個(gè)任務(wù),選擇工程菜單,然后包,然后創(chuàng)建包。 在把應(yīng)用程序部署到真實(shí)設(shè)備之前,我們先測(cè)試程序是否在模擬器中運(yùn)轉(zhuǎn)正確。選擇工程菜單,然后通過OTA運(yùn)行。這個(gè)步驟實(shí)際上是模擬MIDlet的over-the-air安裝。圖9的順序圖描述了全部的過程。保持此模擬器窗口打開。 ![]() 圖9. 通過over the air方法在模擬器中安裝應(yīng)用程序 現(xiàn)在,在KToolbar中進(jìn)入文件菜單,并選擇Utilities。得到一個(gè)彈出窗口,如圖10所示。 ![]() 圖10. 打開Utilities 單擊WMA,然后打開控制臺(tái)。打開了另一個(gè)彈出窗口: ![]() 圖11. 打開WMA Utilities 控制臺(tái) 在窗口中選擇發(fā)送SMS按鈕。窗口的內(nèi)容將會(huì)改變,如圖12所示。在選擇客戶端區(qū)域內(nèi)選擇+5550000作為電話號(hào)碼。在端口文本框中,輸入50001。在消息域中,輸入Hi Test Message?,F(xiàn)在單擊發(fā)送按鈕。 ![]() 圖12. 從Utilities發(fā)送SMS消息 如果在以上步驟中,每一件事都運(yùn)行良好,那么模擬器窗口,如圖13所示,將會(huì)顯示一個(gè)消息到達(dá)了模擬移動(dòng)電話,告訴用戶消息到達(dá)到了,并等到批準(zhǔn)。 ![]() 圖13. 模擬器MIDlet被SMS消息激活 如果你在模擬器上選擇Yes,MIDlet會(huì)自動(dòng)啟動(dòng),”Hi Test Message”會(huì)顯示在模擬器中,如圖14所示。 ![]() 圖14. 模擬器MIDlet接受到SMS 接下來的步驟事在真實(shí)設(shè)備上安裝MIDlet。你可以使用OTA安裝應(yīng)用程序。詳細(xì)內(nèi)容請(qǐng)查閱Sun的工具包文檔。除了OTA,我們可以電纜/紅外線/藍(lán)牙技術(shù)來安裝MIDlet,如果設(shè)備支持那些選項(xiàng)。作為一個(gè)客戶端設(shè)備,我使用Nokia 6600,這是支持紅外線技術(shù)的,并且因?yàn)槲矣幸粋€(gè)紅外線適配器,我使用紅外線技術(shù)在Nokia 6600中安裝MIDlet。 如果以上步驟運(yùn)行良好,你的客戶端應(yīng)用程序就準(zhǔn)備就緒了?,F(xiàn)在是時(shí)候來開發(fā)服務(wù)器端應(yīng)用程序了,實(shí)際上,它將發(fā)送SMS消息給監(jiān)聽50001端口的MIDlet。 開發(fā)服務(wù)器端應(yīng)用程序來將SMS消息發(fā)送到特定的設(shè)備端口 如前所述,為了開發(fā)服務(wù)器端與GSM調(diào)制解調(diào)器交互的的代碼,我使用開源的SMSLib for Java, 它使用關(guān)注指令(AT指令)與GSM調(diào)制解調(diào)器進(jìn)行交互。它同時(shí)也使用Java通信API或RxTx與使用的操作系統(tǒng)通信,并與外部設(shè)備(GSM調(diào)制解調(diào)器)交談來發(fā)送AT指令。 為了發(fā)送消息到指定的端口,用戶數(shù)據(jù)和協(xié)議數(shù)據(jù)單元(PDU)的用戶數(shù)據(jù)標(biāo)題指示(UDHI)域都必須被修改。SMSLib在內(nèi)部完成了它,所以發(fā)送SMS消息引起的復(fù)雜度都被包裝在SMSLib的代碼內(nèi)。如果你對(duì)觀察消息是如何被正確發(fā)送的感興趣,你可以獨(dú)自仔細(xì)檢查SMSLib的代碼。 按照如下的步驟來完成服務(wù)器的編碼和部署: 1.從SMSLib網(wǎng)站下載SMSLib代碼。下載時(shí),確保你下載的是SMSLib-Java-v1.0.1.zip。SMSLib for Java可以跟Java通信API或RxTx一起使用。最近,Sun撤消了了對(duì)Java通信API Windows版的支持,所以使用RxTx會(huì)更好。但如果你已經(jīng)有了Java通信API,你同樣可以用它和SMSLib一起運(yùn)行。在這篇文章中,我將詳述以上兩種運(yùn)行實(shí)例程序的方法。 2.以Java通信API 2.0作為開始,首先,確保你已經(jīng)正確安裝了API。解壓javacomm20-win32.zip。在commapi子目錄中,你將找到如下文件: javax.comm.properties win32com.dll comm..jar 把javax.comm.properties拷貝到你的Java運(yùn)行時(shí)環(huán)境的lib目錄中。把win32com.dll拷貝到你的JRE的bin目錄中。當(dāng)運(yùn)行任何使用SMSLib的程序時(shí),確保comm.jar在classpath中。 為了保證Java通信API被正確的安裝了,從命令框中進(jìn)入到commapi\samples\BlackBox目錄中。按如下方式設(shè)置PATH變量:以我為例,JRE的家目錄為C:\j2sdk1.4.2_03\jre。根據(jù)你的JRE設(shè)置做相應(yīng)的改變。 設(shè)置PATH=.;c:\j2sdk1.4.2_03\jre\bin;。現(xiàn)在,使用如下命令來運(yùn)行Java 黑盒程序: java -classpath .;../../comm..jar;BlackBox.jar; BlackBox。 如果Java通信API被正確的安裝了,那么如圖15所示,會(huì)出現(xiàn)一個(gè)顯示你機(jī)器的可用串口(COM端口)的Swing窗口。關(guān)閉窗口之后,命令框?qū)?huì)包含一些跟你可用的COM端口相關(guān)的行,如下面的示例命令提示輸出所示。記住,依賴于你的PC上的可用端口,Swing窗口和命令行提示的內(nèi)容可能會(huì)有變化。但重要的是,如果你能夠看到GUI和在命令提示框中的如下行(就象下面所示),你可以假設(shè)Java通信API已經(jīng)正確安裝了。在這個(gè)測(cè)試之后,關(guān)閉Swing窗口來中止黑盒程序。 ![]() 圖15. 測(cè)試Java通信API的安裝 實(shí)例命令提示框輸出: COM1: PORT_OWNED COM2: PORT_OWNED Closing port 1 (COM2) Closing COM2 Closing port 0 (COM1) Closing COM1 3.現(xiàn)在,是時(shí)候把GSM調(diào)制解調(diào)器連接到你的電腦上了。我使用一部Nokia 6600移動(dòng)電話作為GSM調(diào)制解調(diào)器。Nokia 6600沒有串口連接器(COM端口連接器)。但是,它提供了紅外線技術(shù)連接到電腦,然后作為GSM調(diào)制解調(diào)器。如果你有一部有串口直接連接器的電話,那樣使用起來會(huì)更簡(jiǎn)單。一般地, 實(shí)際的GSM調(diào)制解調(diào)器會(huì)提供串口連接器。但是如果你的設(shè)備缺少串口連接器,但包含一個(gè)內(nèi)置的GSM調(diào)制解調(diào)器并能使用紅外線或藍(lán)牙技術(shù)連接,這種選擇也能起作用。 為了在沒有物理COM端口的情況下,在功能上實(shí)現(xiàn)COM端,你必須將一個(gè)虛擬的COM端口映射到你的紅外線或藍(lán)牙連接上。SMSLib需要一個(gè)兼容的GSM電話或GSM調(diào)制解調(diào)器。如果提供了調(diào)制解調(diào)器的能力,大多數(shù)GSM電話都能被使用。SMSLib使用串行連接(物理或模擬,比如藍(lán)牙,紅外線,USB等)來與GSM調(diào)制解調(diào)器通信。通過Nokia 6600, 你可以使用SMSLib來發(fā)送SMS消息,但是因?yàn)镹okia 6600把傳入的消息儲(chǔ)存在記憶卡里而不是SIM卡中,使用這種模式將不能接受到這些消息。同樣,Nokia 6600不允許從記憶卡中使用AT指令來讀取消息。但是,我們僅僅需要發(fā)送SMS消息來激活我們的MIDlet,Nokia 6600能夠成功的完成這些(不需要接收SMS消息)。對(duì)于使用紅外線或藍(lán)牙技術(shù)連接的電話來說,最重要的是將紅外線或藍(lán)牙連接映射到一個(gè)虛擬COM端口。參考你的移動(dòng)電話的文檔,查明它是否支持虛擬COM端口映射。 以我為例,我在我的PC上安裝了Nokia PC 套件。為了從我的PC連接Nokia 6600,我使用一個(gè)外部USB紅外適配器。因此,為了這種情況,我也在PC上安裝了紅外線驅(qū)動(dòng)。 現(xiàn)在,我用PC上的USB端口連接到外部紅外適配器。在Nokia 6600設(shè)備上,我選擇菜單,然后連接,然后調(diào)制解調(diào)器。通過紅外線連接的選項(xiàng)在調(diào)制解調(diào)器下面?,F(xiàn)在,我選擇選項(xiàng)“連接”,并把移動(dòng)電話放在紅外適配器的有效范圍之內(nèi)。 4.下一步是驗(yàn)證從PC,我們能夠使用AT指令訪問GSM調(diào)制解調(diào)器。為此,選擇開始菜單,然后程序,然后附件,然后通信,然后超級(jí)終端。會(huì)打開一個(gè)對(duì)話框,并請(qǐng)求一個(gè)邏輯名稱。提供任何你愿意提供的名字。為了方便,我提供名字“GSM Modem”。選擇OK。 ![]() 圖16. 打開超級(jí)終端 5.另一個(gè)彈出窗口出現(xiàn)。在使用連接的下拉菜單中,選擇COM端口名稱(虛擬的或?qū)嶋H的),GSM調(diào)制解調(diào)器將通過此端口連接到PC。以我為例,是COM4。 ![]() 圖17. 在超級(jí)終端中選擇COM端口 6.在下一個(gè)對(duì)話框中(COM端口的屬性),只需單擊OK。 7.現(xiàn)在,你會(huì)被帶到一個(gè)窗口,你將在此窗口中輸入一些命令(以我們?yōu)槔?,我們將輸入AT指令)。輸入如下命令來測(cè)試連通性-但是記住,當(dāng)你輸入指令的時(shí)候,不會(huì)在控制臺(tái)中寫入任何東西:AT+CPMS=?。 要點(diǎn):不要在超級(jí)終端中輸入任何未知的命令。這可能會(huì)永久性損壞你的移動(dòng)設(shè)備或擦去所有的數(shù)據(jù)。 如果一切順利,你將能看到一些輸出,如圖18所示。輸出可能會(huì)不盡相同,但是沒有輸出,輸出錯(cuò)誤,或終端沒有響應(yīng)都代表這連通性的錯(cuò)誤。 ![]() 圖18. 在超級(jí)終端中執(zhí)行AT指令 8.現(xiàn)在從呼叫菜單,使用斷開連接命令從超級(jí)終端斷開連接。 9.完成了如上的步驟后,我們可以準(zhǔn)備寫Java示例程序了。此程序?qū)l(fā)送SMS消息到我們剛才配置的的GSM調(diào)制解調(diào)器的指定端口上: import org.smslib.*; 在如上的代碼片斷中,我們首先使用4個(gè)參數(shù)來創(chuàng)建類CService的一個(gè)實(shí)例。第一個(gè)參數(shù)為COM端口的名稱。(以我為例,這里是COM4,因?yàn)槲业腉SM調(diào)制解調(diào)器是連接到一個(gè)虛擬的COM端口的。確保根據(jù)你的COM端口名稱來改變這里的值。)第二個(gè)參數(shù)指定波特率。當(dāng)調(diào)制解調(diào)器連接時(shí)你會(huì)發(fā)現(xiàn)這一限制。第三個(gè)參數(shù)指定移動(dòng)/GSM調(diào)制解調(diào)器的構(gòu)成。第四個(gè)參數(shù)指定模式。在一個(gè)特定的構(gòu)成和模式需要不同的AT指令集來與GSM調(diào)制解調(diào)器交互的地方,第三和第四參數(shù)有時(shí)啟動(dòng)很重要的作用。例如,對(duì)于Sony Ericsson模式,需要一個(gè)不同的AT指令集和邏輯;因此,伴隨著jSMSEngine發(fā)行版,你能找到一個(gè)單獨(dú)的對(duì)于Sony Ericsson的處理包。對(duì)于特定類型的構(gòu)成和模式,jSMSEngine有不同的處理包。對(duì)于Nokia,缺省的處理包對(duì)于Nokia 6600 和我們的目的已經(jīng)足夠好了。因此,我沒有對(duì)第三和第四個(gè)參數(shù)指定任何值。 CService被初始化之后,我們使用connect()方法連接到GSM調(diào)制解調(diào)器。我們?cè)O(shè)置SMSC數(shù)字(SMS中心數(shù)字)為空。這會(huì)被SIM卡得到。在那之后,我們使用類CoutgoingMessage()創(chuàng)建一個(gè)發(fā)出的消息。COutgoingMessage()的構(gòu)造函數(shù)需要兩個(gè)參數(shù):發(fā)送消息的設(shè)別數(shù)字和消息本身。在一個(gè)典型的實(shí)際的應(yīng)用程序中,一些類似于數(shù)字代碼的指示符會(huì)被作為SMS消息發(fā)送;根據(jù)那個(gè)代碼,在MIDlet端會(huì)發(fā)生一些動(dòng)作。另外一個(gè)要點(diǎn)是setDestinationPort()方法,在這里我們?cè)O(shè)定目標(biāo)端口。 圖19展示了詳細(xì)的建立過程。 ![]() 圖19. 詳細(xì)的建立過程 重要注解:SMSLib在CLogger.java中使用了J2SE 5.0的API。CLogger.java中有一行使用PrintStream的構(gòu)造函數(shù),并用java.io.File類型作為參數(shù)。這個(gè)PrintStream類中的構(gòu)造函數(shù)從J2SE 5.0才有支持。但是由于我使用J2SE 1.4,我把那一行從:stream = new PrintStream(new File(filename)); 改成:stream = new PrintStream(new FileOutputStream(filename)); 改變之后,我構(gòu)建了SMSLib提供的源代碼,并創(chuàng)建了新的JAR使用JRE 1.4.2。 10.為了編譯示例程序,確保在你的classpath中有新的JAR(是你在修改CLogger代碼后生成的)和comm.jar。然后編譯示例應(yīng)用程序。 11.編譯完成之后,運(yùn)行應(yīng)用程序。確保之前步驟提到的JAR在classpath中。如果一切順利,你能夠看到你安裝在另外一個(gè)設(shè)備中MIDlet已經(jīng)自動(dòng)啟動(dòng)了,并顯示你的消息。 現(xiàn)在,讓我們看看如何使用RxTx來代替Java通信API 2.0。你可以從SMSLib下載RxTx。當(dāng)使用RxTx的時(shí)候,我們需要注意如下幾點(diǎn): 1.拷貝RXTXComm.jar到(JDKDIR)\jre\lib\ext目錄,拷貝rxtxSerial.dll文件到(JDKDIR)\jre\bin目錄。 2.為了使用,SMSLib同Java通信API一起打包,但是進(jìn)行一小部分的代碼修改,我們也能讓它跟RxTx一起使用。為了讓SMSLib同RxTx一起使用,修改CSerialDriver.java并刪除行javax.comm.*;。添加行import gnu.io.*;。然后重新生成。 3.RxTx也支持Win32。當(dāng)我寫這篇文章的時(shí)候,RxTx能很好的支持物理串行連接,但是對(duì)于“虛擬”串行端口則有些例外,例如,通過藍(lán)牙/紅外線/USB連接模擬串行端口。但是,在顯示生活的情況中,你不會(huì)使用一個(gè)移動(dòng)電話作為調(diào)制解調(diào)器,而是一個(gè)真實(shí)的GSM調(diào)制解調(diào)器,它將通過真實(shí)的COM(串行)端口來連接。這將不會(huì)成為問題。現(xiàn)在,以我為例,在發(fā)送SMS消息時(shí)我接受到了一些錯(cuò)誤,因?yàn)槲业募t外線連接有一個(gè)虛擬的端口映射。為了消除那些錯(cuò)誤,我在CSerialDriver中注釋掉了一些行。特別的,找到outStream.flush();,注釋掉,然后重新生成。 4.現(xiàn)在,按照上面列表中的步驟3開始。在步驟11中,確保當(dāng)運(yùn)行SendMessageWithPortsSMSLib的時(shí)候,在你的classpath中有最近生成的JAR(對(duì)于RxTx的改變),同時(shí)保證使用RXTXcomm.jar和rxtxSerial.dll文件代替Java通信API的comm.jar和相應(yīng)的dll文件。 注意的要點(diǎn):因?yàn)镾MSLib使用Java通信API,或者RxTx,這些會(huì)對(duì)操作系統(tǒng)進(jìn)行本地調(diào)用,我建議不要將這些代碼直接嵌入到應(yīng)用程序服務(wù)器或Web服務(wù)器。一個(gè)可選的解決方案是將這些代碼嵌入到一個(gè)單獨(dú)的RMI(遠(yuǎn)程方法調(diào)用)服務(wù)器或Web service服務(wù)器,然后從應(yīng)用服務(wù)器來訪問他。但是,因?yàn)槲覀兪褂肎SM調(diào)制解調(diào)器,SMS的發(fā)送速度很低;所以如果我們直接調(diào)用接口(RMI或Web service),最好使用異步設(shè)計(jì)。例如,當(dāng)你試著發(fā)送一條消息到設(shè)備,將必須的信息(移動(dòng)號(hào)碼,端口,消息等)放到一個(gè)Java消息服務(wù)隊(duì)列中。寫一個(gè)消息驅(qū)動(dòng)的bean來采集消息,然后使用一個(gè)Web service來調(diào)用服務(wù)(嵌入在SMS發(fā)送代碼中)。 我談到了一種可行的方式;你可以選擇任何最適合你的架構(gòu)的設(shè)計(jì)。但是當(dāng)做任何決定的時(shí)候,緊記如下兩點(diǎn): 使用GSM調(diào)制解調(diào)器,發(fā)送SMS消息的速度不是很快(依賴與你選擇的GSM調(diào)制解調(diào)器和SMS服務(wù)提供商) SMSLib使用Java通信API或RxTx,這將對(duì)操作系統(tǒng)發(fā)生本地調(diào)用 雖然我建議使用兩個(gè)Nokia 6600移動(dòng)設(shè)置(一個(gè)作為GSM調(diào)制解調(diào)器,另一個(gè)作為Java ME客戶端),你可以僅僅使用一個(gè)來測(cè)試此行為。首先,把MIDlet安裝在設(shè)備上。然后使用相同的設(shè)備作為GSM調(diào)制解調(diào)器。當(dāng)發(fā)送SMS消息時(shí),把消息發(fā)送到與你作為發(fā)送消息的GSM調(diào)制解調(diào)器的移動(dòng)設(shè)備相同的移動(dòng)號(hào)碼上。在這中情況下,發(fā)送者和接收者移動(dòng)電話是相同的。 總 結(jié) 在這篇文章中,你學(xué)到了如何使用push注冊(cè)特征來寫Java ME應(yīng)用程序。同時(shí),你也學(xué)到了如何從服務(wù)器發(fā)送一條SMS消息,然后自動(dòng)啟動(dòng)MIDlet。為了僅僅測(cè)試push注冊(cè)特征,你可以使用兩部支持MIDP 2.0和WMA1.1的手機(jī)(不需要服務(wù)器端SMS push),和Sun Java Wireless Toolkit提供的SMSSend和SMSRecieve示例程序。但是在實(shí)際應(yīng)用程序中,你可能需要從服務(wù)器發(fā)送SMS消息,而不是從另一個(gè)MIDlet。 在本文中展示的代碼片斷不是很復(fù)雜;搭建環(huán)境的步驟卻很復(fù)雜。但是一旦正確地搭建了環(huán)境,你會(huì)很興奮的看到使用服務(wù)器端SMS push,push注冊(cè)特征在真實(shí)的設(shè)備上運(yùn)行。如果你在使用SMSLib時(shí)遇到任何問題,你總是可以發(fā)布問題和向SMSLib用戶組請(qǐng)求幫助。最后,我要感謝SMSLib項(xiàng)目的所有者Thanasis Delenikas分享了一些關(guān)于SMSLib最近開發(fā)中的有價(jià)值的信息。 關(guān) 于 作 者 Srijeeb Roy擁有印度加爾各答Jadavpur大學(xué)計(jì)算機(jī)科學(xué)和工程學(xué)的學(xué)士學(xué)位。他目前作為技術(shù)架構(gòu)師,在Tata Consultancy Services Limited公司的一個(gè)基于Java EE的項(xiàng)目中工作。他在Java/Java EE的領(lǐng)域中工作了6年以上,在IT工業(yè)擁有總共多余7年的經(jīng)驗(yàn)。他為他的公司和客戶開發(fā)了多個(gè)Java的內(nèi)部框架。他也工作在多個(gè)其他的領(lǐng)域,比如Forte,CORBA和Java ME。 資 源 下載文章中的源代碼: http://www./javaworld/jw-04-2006/push/jw-0417-push.zip 下載Sun Java Wireless Toolkit: http://java./products/sjwtoolkit/ 下載SMSLib: http:/// RxTx主頁: http:/// |
|