背景與動機
- 手機發短信:輸入慢、存儲少、功能受限。
- 網關發送 (126/新浪/網關租用):需聯網、成本高、隱私風險。
- 數據線 + Java Comm API 方案:成本 = 短信費、離線可用、電腦全鍵盤輸入、數據本地存儲、可擴展群發/定時/模板功能。
硬體連接
- 手機數據線 → **COM 口 (串口)** 或 USB (轉虛擬 COM)。本文採用 COM 口,編程模型更簡單。
- 波特率、數據位、停止位、奇偶校驗需與手機模組匹配 (通常 9600/115200, 8N1)。
Sun Java Communications API 安裝步驟 (JDK 1.5 示例)
- 下載
commapi.zip 解壓至 C:\commapi。
- 複製
win32com.dll → C:\jdk1.5\bin\ (JRE 對應 bin 目錄)。
- 複製
comm.jar → C:\jdk1.5\lib\ (或 jre\lib\ext\)。
- 複製
javax.comm.properties → C:\jdk1.5\lib\ (關鍵:指定平台驅動類 Driver=com.sun.comm.Win32Driver,否則掃描不到端口)。
- 將
comm.jar 加入項目 Classpath。
核心編程模型
// 1. 獲取端口標識符
CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier("COM1");
// 2. 打開端口
SerialPort serialPort = (SerialPort) portId.open("SMSApp", 2000);
// 3. 配置參數
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
// 4. 獲取輸入/輸出流
OutputStream out = serialPort.getOutputStream();
InputStream in = serialPort.getInputStream();
// 5. 發送 AT 指令 (需按手機模組協議)
out.write("AT+CMGF=1\r\n".getBytes()); // 文本模式
out.write("AT+CMGS=\"13800000000\"\r\n".getBytes()); // 目標號碼
out.write("Hello from Java!\x1A".getBytes()); // 內容 + Ctrl+Z (0x1A) 結束
// 6. 讀取響應 (OK/ERROR/+CMGS: ...)
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
System.out.println("手機響應: " + line);
if (line.contains("OK") || line.contains("ERROR")) break;
}
// 7. 關閉資源
out.close(); in.close(); serialPort.close();
關鍵注意點
- AT 指令集差異:不同手機/模組 (Wavecom, Siemens, Sony Ericsson 等) 指令細節不同,需查閱對應手冊。
- 編碼:中文短信需 PDU 模式或 UCS2 編碼,文本模式僅支援 GSM 7-bit 字符集。
- 流控制:高速傳輸建議啟用 RTS/CTS 硬件流控 (
setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT))。
- 異常處理:端口被佔用 (
PortInUseException)、參數不支持 (UnsupportedCommOperationException)、IO 異常。
- 現代替代方案:
jSerialComm (純 Java、無需安裝 DLL、跨平台、API 更現代)、RXTX (Comm API 開源移植)。**新項目首選 jSerialComm**。
擴展應用
- 短信貓 (GSM Modem) 批量發送/接收。
- USSD 碼查詢話費/流量。
- GPS 定位數據讀取 (NMEA 協議)。
- 嵌入式設備/單片機/儀器儀表串口通訊。