本文將詳細講解Wireless Messaging API(WMA,JSR120),WMA提供給應用開發者一個通用的API用于開發基于無線消息服務的應用程序,比如短消息服務。目前支持的發送類型為文本和二進制兩種。
在講解WMA的結構和使用方法前,我們先來從感性上熟悉一下WMA。在SUN Wireless Toolkit 20中包括了一個短消息的范例。在運行Demo程序以前我們先看一下jad文件的內容,這可以幫助我們迅速了解應用程序的信息:
CBS-Message-Identifier: 50001
MIDlet-1: SMS Send, /icons/App.png, example.sms.SMSSend
MIDlet-2: SMS Receive, /icons/App.png, example.sms.SMSReceive
MIDlet-3: CBS Receive, /icons/App.png, example.cbs.CBSReceive
MIDlet-Data-Size: 0
MIDlet-Description: This midlet demonstrates SMS and CBS messaging
MIDlet-Jar-Size: 8569
MIDlet-Jar-URL: SMSDemo.jar
MIDlet-Name: SMS Demo
MIDlet-Permissions: javax.microedition.io.PushRegistry, javax.microedition.io.Connector.sms, javax.wireless.messaging.sms.receive,javax.wireless.messaging.sms.send,javax.microedition.io.Connector.cbs,javax.wireless.messaging.cbs.receive
MIDlet-Push-1: sms://:50000, example.sms.SMSReceive, *
MIDlet-Push-2: cbs://:50001, example.cbs.CBSReceive, *
MIDlet-Vendor: Sun Microsystems, Inc.
MIDlet-Version: 2.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-PRofile: MIDP-2.0
SMS-Port: 50000
從上述信息中我們可以看出,MIDlet套件中共包括三個MIDlet,分別是SMSSend,SMSReceive和CBSReceive。我們最應該關注的是兩個MIDlet-Push實體,他們可以使得應用程序監聽SMS和CBS消息,當收到消息后AMS將激活相關的MIDlet來進行處理,套件需要使用MIDP2.0的新特性——Push。因此如果想正確運行這個應用程序,必須通過OTA定購的模式進行安裝。具體Push實體的屬性含義這里不過多進行解釋。
WTK提供了WMA Console工具,可以和模擬器配合使用來調試基于無線短消息服務的應用程序。首先我們打開Ktoolbar選擇SMSDemo項目,編譯并打包后,從Project—>Run via OTA開始安裝應用程序,按照提示一步一步進行安裝。安裝后運行應用程序,系統為它分配手機號碼為5550000。
然后我們從WTK中選擇Utilities—WMA Console,打開的時候系統會分配一個號碼,比如5550001。選擇SMS Send在用戶界面中輸入號碼5550001(WMA Console的號碼),在消息內容中輸入Hello選擇發送。這時候我們可以在WMA Console中看到從模擬器中發送過來的消息,如下圖所示:
同樣,我們也可以使用WMA Console來發送短消息給模擬器,選擇Send SMS然后在客戶端的電話號碼中選擇5550000(模擬器的電話號碼),端口為50000,在消息中輸入How are you?并點擊發送按鈕。
我們的SMSDemo中使用了Push特性,因此在WMA Console在向模擬器發送短消息數據的時候,AMS會自動激活example.sms.SMSReceive,接收短消息內容。
WMA Console也提供了發送CBS消息的功能,與SMS類似這里略去不講。
下面的部分詳細講解WMA的結構和使用方法。WMA是基于通用連接框架(Generic Connection Framework,GCF)的可選包,這又一次說明了GCF出色的擴展特性。所有的WMA組件都包括在javax.wireless.messaging包內。在這個包內定義了所有用于發送、接受短消息的接口,短消息的類型支持文本和二進制兩種。下圖是WMA組件結構圖:
WMA的主要組件包括:Message、TextMessage、BinaryMessage、MessageConnection和MessageListener。其中Message接口定義了不同類型短消息的基礎部分,它的兩個子類BinaryMessage和TextMessage分別代表了文本類型和二進制類型的消息,通過調用BinaryMessage的setPayloadData()和TextMessage的setPayloadText()方法可以把有效負載數據添加到數據容器中,然后進行發送。MessageConnection接口是擴展了GCF中定義的Connection接口,MessageConnection接口提供了newMessage(),send()和receive()方法來創建、發送和接受消息對象。MessageListener實現了監聽器設計模式用于異步接受消息,當等待消息到來的時候系統不用堵塞。每次有消息到來的時候,平臺會調用MessageListener中定義的notifyIncomingMessage()方法。
使用WMA非常簡單,下面我們進行簡單的講述:
1. 創建MessageConnection
創建MessageConnection通常有兩種方式,一種是按照客戶端方式創建,客戶端方式創建的MessageConnection只能用于發送短消息。我們需要在URL中提供電話號碼和端口,如下:
(MessageConnection)Connector.open("sms://+5121234567:5000");
另一種創建方式是服務器連接,這種連接方式可以用于發送和接收短消息。
(MessageConnection)Connector.open("sms://:5000");
2. 發送短消息
通過MessageConnection提供的newMessage()方法,我們可以創建Message對象,通過指定短消息類型為BINARY_MESSAGE或者TEXT_MESSAGE可分別得到二進制和文本類型的消息對象。如果我們是使用客戶端連接,那么在我們創建MessageConnection的時候,傳入的URL將作為Message對象的目標地址。如果我們是使用服務器連接,那么我需要使用setAddress()方法設置目標地址。下面的代碼說明了如何發送短消息。
String address = destinationAddress + ":" + smsPort;
MessageConnection smsconn = null;
try {
/** Open the message connection. */
smsconn = (MessageConnection)Connector.open(address);
TextMessage txtmessage = (TextMessage)smsconn.newMessage(
MessageConnection.TEXT_MESSAGE);
txtmessage.setAddress(address);
txtmessage.setPayloadText(messageBox.getString());
smsconn.send(txtmessage);
} catch (Throwable t) {
System.out.println("Send caught: ");
t.printStackTrace();
}
if (smsconn != null) {
try {
smsconn.close();
} catch (IOException ioe) {
System.out.println("Closing connection caught: ");
ioe.printStackTrace();
}
}
}
發送二進制短消息和發送文本消息非常類似,我們只是需要把byte[]來代替String作為發送的數據。范例代碼如下:
public void sendBinaryMessage(MessageConnection mc, byte[]
msg, String url) {
try {
BinaryMessage bmsg =
(BinaryMessage)mc.newMessage
(MessageConnection.BINARY_MESSAGE);
if (url!= null)
bmsg.setAddress(url);
bmsg.setPayloadData(msg);
mc.send(bmsg);
}
catch(Exception e) {
// Handle the exception...
System.out.println("sendBinaryMessage " + e);
}
}
3. 接收短消息
只有作為服務器連接的時候才可以接受短消息,接收短消息的時候我們需要單獨啟動一個線程來處理。調用receive()方法后,我們需要首先判斷Message的類型是二進制還是文本,只有這樣才可以調用正確的方法來接收數據。
public void processMessage() {
Message msg = null;
// Try reading (maybe block for) a message
try {
msg = mc.receive();
}
catch (Exception e) {
// Handle reading errors
System.out.println("processMessage.receive " + e);
}
// Process the received message
if (msg instanceof TextMessage) {
TextMessage tmsg = (TextMessage)msg;
// Handle the text message...
ticker.setString(tmsg.getPayloadText());
}
else {
// process received message
if (msg instanceof BinaryMessage) {
BinaryMessage bmsg = (BinaryMessage)msg;
byte[] data = bmsg.getPayloadData();
// Handle the binary message...
}
else {
// Ignore
}
}
}
}
4. 使用MessageListener
如果我們的MIDlet注冊了一個MessageListener,那么當收到短消息的時候平臺就會調用notifyIncomingMessage()方法來進行處理。其實這和MIDP圖形用戶界面中的回調機制是一樣的。通常使用MessageListener按照如下的步驟,首先定義MIDlet實現MessageListener接口,當然你也可以選擇不使用MIDlet來實現MessageListener。接下來我們需要實現MessageListener的方法notifyIncomingMessage()。最后MessageConnection需要注冊MessageListener,在應用程序結束的時候你最好注銷它,調用setMessageListener(null)。
本文沒有提供完整的范例,讀者可以參考WTK中提供的SMSDemo。
(出處:http://www.49028c.com)
新聞熱點
疑難解答