MIDP 2.0 引入 PushRegistry 類別,允許 MIDlet 透過定時鬧鐘或入站網路連線 (SMS、Socket、Datagram) 自動啟動。這讓應用能處理排程同步、即時推播等進階場景,無需使用者手動啟動。
// 動態註冊 (執行時)
static String registerAlarm(String midlet, long time); // 毫秒時間戳
static void registerConnection(String connection, String midlet, String filter);
static void unregisterConnection(String connection);
// 靜態查詢
static String[] listConnections(boolean available);
static String getMIDlet(String connection);
static String getFilter(String connection);
static long listConnections(String midlet); // 註冊的鬧鐘時間
| 類型 | URL 格式 | 說明 |
|---|---|---|
| SMS | sms://:port | 所有 Motorola、多數 Nokia 支援 |
| TCP Socket | socket://:port | 理論支援,實機罕見 |
| UDP Datagram | datagram://:port | 2005 後期機型支援 (V3X、E1070 等) |
// WAP/OTA/SyncML 相關保留埠
2805, 2923, 2948, 2949, 5502, 5503, 5508, 5511, 5512,
9200, 9201, 9202, 9203, 9207, 49996, 49999
// 完整清單請參考 JSR 120 附錄 A.6.0
public class PushDemoMIDlet extends MIDlet {
private static final int SMS_PORT = 50000;
private static final int DATAGRAM_PORT = 50001;
protected void startApp() {
// 註冊 SMS Push
try {
PushRegistry.registerConnection(
"sms://:" + SMS_PORT,
this.getClass().getName(),
"*" // 接受所有發送者
);
} catch (Exception e) { e.printStackTrace(); }
// 註冊 Datagram Push (若裝置支援)
try {
PushRegistry.registerConnection(
"datagram://:" + DATAGRAM_PORT,
this.getClass().getName(),
"*"
);
} catch (Exception e) { /* 忽略不支援 */ }
// 排程 1 小時後自動啟動
scheduleAlarm(60 * 60 * 1000);
}
private void scheduleAlarm(long delayMs) {
try {
long alarmTime = System.currentTimeMillis() + delayMs;
long registered = PushRegistry.registerAlarm(
this.getClass().getName(), alarmTime);
System.out.println("Alarm registered at: " + new Date(registered));
} catch (Exception e) { e.printStackTrace(); }
}
protected void destroyApp(boolean unconditional) {
// 清理資源後重新排程
scheduleAlarm(DEFAULT_INTERVAL);
}
}
MIDlet-Name: PushDemo
MIDlet-Version: 1.0
MIDlet-Vendor: Example
MIDlet-1: PushDemo,,PushDemoMIDlet
MicroEdition-Configuration: CLDC-1.1
MicroEdition-Profile: MIDP-2.0
# SMS Push 靜態註冊
MIDlet-Push-1: sms://:50000, PushDemoMIDlet, *
# Datagram Push 靜態註冊
MIDlet-Push-2: datagram://:50001, PushDemoMIDlet, *
# IP 過濾器支援通配符
MIDlet-Push-3: socket://:6000, PushDemoMIDlet, 192.168.1.*
protected void startApp() {
String[] connections = PushRegistry.listConnections(true);
if (connections == null || connections.length == 0) {
// 使用者手動啟動
showMainMenu();
} else {
// 由 Push 觸發啟動
for (String conn : connections) {
if (conn.startsWith("sms://")) {
handleSMSPush(conn);
} else if (conn.startsWith("datagram://")) {
handleDatagramPush(conn);
} else if (conn.startsWith("socket://")) {
handleSocketPush(conn);
}
}
}
}
private void handleSMSPush(String connUrl) {
try {
MessageConnection msgConn = (MessageConnection) Connector.open(connUrl);
Message msg = msgConn.receive();
if (msg instanceof TextMessage) {
String text = ((TextMessage) msg).getPayloadText();
processCommand(text);
}
msgConn.close();
} catch (IOException e) { e.printStackTrace(); }
}
| 狀況 | AMS 行為 |
|---|---|
| MIDlet 正在執行,收到 Push | 忽略觸發,MIDlet 繼續執行 (需自行處理連線) |
| MIDlet 未執行,收到 Push | 自動啟動 MIDlet |
| 其他 MIDlet 執行中,收到 Push | 詢問使用者是否切換 (同意則終止當前 MIDlet) |
| 多個 Push 訊息排隊 | 最多佇列 5 個,依序處理 |
| 無對應註冊 | 忽略訊息 |
ConnectionNotFoundException:協定/埠不支援SecurityException:權限不足 (需簽名或使用者授權)IllegalArgumentException:URL 格式錯誤或埠號保留ClassNotFoundException:MIDlet 類別名稱錯誤listConnections(true) 判斷觸發來源MessageConnection 釋放埠口System.currentTimeMillis() 絕對時間destroyApp() 中重新排程下次鬧鐘善用 Push Registry,您的 J2ME 應用將具備「隨時在線」的感知能力,大幅提升使用者體驗與應用價值。