前段時間,網絡不好,Blog很難上,就沒管了,今天上來一看,居然快一個月沒來了,唉~~鬱悶.
一個月前,看了下短信收發的資料,就寫了下面這些個東西:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;
/*
* Created on 2005-4-18 10:36:39
*
*/
/**
* @author zxub
*
*/
public class CommConnection implements SerialPortEventListener {
private Enumeration portList;
private String portName;
private CommPortIdentifier portId;//串口管理器,負責打開,調用,和初始化串口等管理工作
private SerialPort serialPort=null;
private int getReplyInterval;
private int commandDelay;
private String replyString;
private InputStream inputStream=null;
private OutputStream outputStream=null;
private int Baudrate;
private String sendMode;
private String message;
private int msgCount = 0;
public boolean errFlag = false;
public CommConnection() {
getSysConfig();
}
public void getSysConfig()
{
OperaXML ox = new OperaXML();
ox.read("config.xml");
this.portName = ox.getNodeValue("Config1/PortName");
this.Baudrate = Integer.parseInt(ox.getNodeValue("Config1/BAUDRATE"));
this.sendMode = ox.getNodeValue("Config1/SendMode");
this.getReplyInterval = Integer.parseInt(ox
.getNodeValue("Config1/GetReplyInterval"));
this.commandDelay = Integer.parseInt(ox
.getNodeValue("Config1/CommandDelay"));
ox.close();
}
//********************************************************************
//列出所有串口
public void listSerialPort() {
// CommPortIdentifier類的getPortIdentifiers方法可以找到系統所有的串口,
//每個串口對應一個CommPortIdentifier類的實例。
portList=null;
portId=null;
portList = CommPortIdentifier.getPortIdentifiers();
returnStateInfo("串口列表:");
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
/* 如果端口類型是串口,則打印出其端口信息 */
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
returnStateInfo(portId.getName());
}
}
returnStateInfo("串口列表顯示結束!");
}
//********************************************************************
//********************************************************************
public void getSerialPort() {
if (this.errFlag == true)
return;
returnStateInfo("檢查連接情況...");
if (this.portName == "") {
returnStateInfo("串口號爲空,請檢查配置文件!");
this.errFlag = true;
return;
//System.out.println("Portname is null, get err, the program now
// exit!");
//System.exit(0);
}
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if ((portId.getPortType() == CommPortIdentifier.PORT_SERIAL)
&& portId.getName().equalsIgnoreCase(this.portName)) {
try {
this.serialPort = (SerialPort) portId.open("SendSms", 2000);
} catch (PortInUseException e) {
returnStateInfo("獲取" + this.portName + "時出錯!原因:"
+ e.getMessage());
this.errFlag = true;
return;
}
}
}
}
public void listenSerialPort() {
if (this.errFlag == true)
return;
if (this.serialPort == null) {
returnStateInfo("不存在" + this.portName + ",請檢查相關配置!");
this.errFlag = true;
return;
}
//設置輸入輸出流
try {
outputStream = (OutputStream) this.serialPort.getOutputStream();
inputStream = (InputStream) this.serialPort.getInputStream();
} catch (IOException e) {
returnStateInfo(e.getMessage());
}
try {
//監聽端口
this.serialPort.notifyOnDataAvailable(true);
this.serialPort.notifyOnBreakInterrupt(true);
this.serialPort.addEventListener(this);
} catch (TooManyListenersException e) {
this.serialPort.close();
returnStateInfo(e.getMessage());
}
try {
this.serialPort.enableReceiveTimeout(20);
} catch (UnsupportedCommOperationException e) {
}
//設置端口的基本參數
try {
this.serialPort.setSerialPortParams(this.Baudrate,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
}
} //********************************************************************
//********************************************************************
//對串口的讀寫操作
public void writeToSerialPort(String msgString) {
try {
this.outputStream.write(msgString.getBytes());
//CTRL+Z=(char)26
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
private void waitForRead(int waitTime) {
try {
Thread.sleep(waitTime);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public String readFromSerialPort(String messageString) {
int strLength;
String messageStr;
String returnString;
strLength = messageString.length();
messageStr = messageString.substring(strLength - 4, strLength - 2);
if (messageStr.equals("OK")) {
returnString = messageStr;
} else {
returnString = messageString;
}
messageStr = messageString.substring(strLength - 7, strLength - 2);
if (messageStr.equals("ERROR")) {
returnString = messageStr;
}
return returnString;
}
//********************************************************************
//********************************************************************
//操作結束,關閉所用資源
public void closeSerialPort() {
if (this.serialPort != null) {
try {
this.serialPort.close();
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
returnStateInfo("已斷開連接!");
}
public void closeIOStream() {
if (this.inputStream!=null)
{
try {
this.inputStream.close();
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
if (this.outputStream!=null)
{
try {
this.outputStream.close();
} catch (IOException e1) {
System.out.println(e1.getMessage());
}
}
//returnStateInfo("已關閉I/O流!");
}
//********************************************************************
public void setToNull()
{
if (this.serialPort!=null) this.serialPort.close();
this.serialPort = null;
this.inputStream=null;
this.outputStream=null;
}
//********************************************************************
//監聽事件
public void serialEvent(SerialPortEvent e) {
StringBuffer inputBuffer = new StringBuffer();
int newData = 0;
switch (e.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE ://DATA_AVAILABLE - 有數據到達
while (newData != -1) {
try {
newData = this.inputStream.read();
if (newData == -1) {
break;
}
if ('/r' == (char) newData) {
inputBuffer.append('/n');
} else {
inputBuffer.append((char) newData);
}
} catch (IOException ex) {
System.err.println(ex);
return;
}
}
this.message = this.message + new String(inputBuffer);
break;
case SerialPortEvent.BI ://BI - 通訊中斷.
System.out.println("/n--- BREAK RECEIVED ---/n");
}
}
//*****************************************************************
//*****************************************************************
//信息發送
public void sendmsg(String messageString, String phoneNumber) {
boolean sendSucc = false;
getSerialPort();
listenSerialPort();
checkConn();
if (this.errFlag == true)
return;
int msglength;
String sendmessage, tempSendString;
returnStateInfo("開始發送...");
switch (Integer.parseInt(this.sendMode)) {
case 0 ://按PDU方式發送
{
this.message = "";
writeToSerialPort("AT+CMGF=0/r");
waitForRead(this.commandDelay);
msglength = messageString.length();
if (msglength < 8) {
tempSendString = "000801" + "0"
+ Integer.toHexString(msglength * 2).toUpperCase()
+ asc2unicode(new StringBuffer(messageString));
} else {
tempSendString = "000801"
+ Integer.toHexString(msglength * 2).toUpperCase()
+ asc2unicode(new StringBuffer(messageString));
}
//"000801"說明:分爲00,08,01,
//"00",普通GSM類型,點到點方式
//"08",UCS2編碼
//"01",有效期
if (phoneNumber.trim().length() > 0) {
String[] infoReceiver = phoneNumber.split(",");
int receiverCount = infoReceiver.length;
if (receiverCount > 0) {
for (int i = 0; i < receiverCount; i++) {
sendmessage = "0011000D91" + "68"
+ changePhoneNumber(infoReceiver[i])
+ tempSendString;
this.replyString = readFromSerialPort(this.message);
if (!this.replyString.equals("ERROR")) {
this.message = "";
writeToSerialPort("AT+CMGS="
+ (msglength * 2 + 15) + "/r");
waitForRead(this.commandDelay);
writeToSerialPort(sendmessage);
try {
outputStream.write((char) 26);
} catch (IOException ioe) {
}
getReply();
if (this.replyString.equals("OK")) {
returnStateInfo("成功發送到 "
+ infoReceiver[i]);
}
if (this.replyString.equals("ERROR")) {
System.out.println("發送給 "
+ infoReceiver[i] + " 時失敗!");
}
}
}
}
}
break;
}
case 1 ://按文本方式發送,不能發送中文
{
this.message = "";
writeToSerialPort("AT+CMGF=1/r");
waitForRead(this.commandDelay);
if (phoneNumber.trim().length() > 0) {
String[] infoReceiver = phoneNumber.split(",");
int receiverCount = infoReceiver.length;
if (receiverCount > 0) {
for (int i = 0; i < receiverCount; i++) {
this.replyString = readFromSerialPort(message);
if (!this.replyString.equals("ERROR")) {
writeToSerialPort("AT+CMGS=" + infoReceiver[i]
+ "/r");
waitForRead(this.commandDelay);
writeToSerialPort(messageString);
try {
outputStream.write((char) 26);
} catch (IOException ioe) {
}
getReply();
if (this.replyString.equals("OK")) {
returnStateInfo("成功發送到 "
+ infoReceiver[i]);
}
if (this.replyString.equals("ERROR")) {
System.out.println("發送給 "
+ infoReceiver[i] + " 時失敗!");
}
}
}
}
}
break;
}
default : {
returnStateInfo("發送方式不對,請檢查配置文件!");
System.exit(0);
break;
}
}
closeIOStream();
closeSerialPort();
message = "";
returnStateInfo("發送完畢!");
}
//*****************************************************************
//*****************************************************************
//讀取所有短信
public void readAllMessage(int readType) {
getSerialPort();
listenSerialPort();
checkConn();
if (this.errFlag == true)
return;
returnStateInfo("開始獲取信息,可能要些時間,請等待...");
String tempAnalyseMessage = "";
writeToSerialPort("AT+CMGF=0/r");
waitForRead(this.commandDelay);
this.message = "";
writeToSerialPort("AT+CMGL=" + readType + "/r");
waitForRead(this.commandDelay);
try {
getReply();
StringTokenizer st = new StringTokenizer(this.message.substring(12,
this.message.length() - 2), "+");
int stCount = st.countTokens();
if (stCount > 0) {
while (st.hasMoreElements()) {
String tempStr = st.nextToken();
this.msgCount += 1;
try {
returnStateInfo(analyseMessage(tempStr.substring(15, tempStr.length()).trim()));
} catch (Exception e) {
returnStateInfo("沒有符合條件的信息!");
}
}
}
} catch (Exception e) {
}
returnStateInfo("信息獲取結束!");
closeIOStream();
closeSerialPort();
this.message = "";
}
//*****************************************************************
//*****************************************************************
//讀取指定短信
public void readMessage(int msgIndex) {
getSerialPort();
listenSerialPort();
checkConn();
if (this.errFlag == true)
return;
String[] tempAnalyseMessage =null;
writeToSerialPort("AT+CMGF=0/r");
waitForRead(this.commandDelay);
this.message = "";
if (msgIndex < 10) {
writeToSerialPort("AT+CMGR=0" + msgIndex + "/r");
} else {
writeToSerialPort("AT+CMGR=" + msgIndex + "/r");
}
waitForRead(this.commandDelay);
try {
getReply();
String tempStr = this.message.substring(12,
this.message.length() - 2);
try {
returnStateInfo(analyseMessage(tempStr.substring(15,tempStr.length()).trim()));
} catch (Exception e) {
returnStateInfo("信息索引有誤!");
}
} catch (Exception e) {
}
closeIOStream();
closeSerialPort();
this.message = "";
}
//*****************************************************************
//*****************************************************************
//對短信息進行分析
public String analyseMessage(String msgString) {
int phoneNumberLength;
int msgLength;
String phoneNumber;
String msgInfo;
String msgTime;
phoneNumberLength = Integer.parseInt(msgString.substring(20, 22), 16);
if (phoneNumberLength % 2 != 0) {
phoneNumberLength = phoneNumberLength + 1;
}
phoneNumber = changePhoneNumber(msgString.substring(24,
24 + phoneNumberLength));
phoneNumber=phoneNumber.replaceFirst("86","").replaceFirst("F","");
msgTime = changePhoneNumber(msgString.substring(
24 + phoneNumberLength + 4, 24 + phoneNumberLength + 5 + 11));
msgTime = fixInfoTime(new StringBuffer(msgTime));
//msgTime=msgTime.substring(0,msgTime.length()-3);
msgLength = Integer.parseInt(msgString.substring(
24 + phoneNumberLength + 5 + 13,
24 + phoneNumberLength + 5 + 15), 16);
msgInfo = msgString.substring((24 + phoneNumberLength + 5 + 15),
(24 + phoneNumberLength + 5 + 15 + msgLength * 2));
String analysedMessage=msgTime+" "+phoneNumber+"/n"+unicode2asc(msgInfo)+"/n";
return(analysedMessage);
}
//*****************************************************************
//*****************************************************************
//對短信時間進行處理
public String fixInfoTime(StringBuffer msgBuffer) {
//msgBuffer.insert(12, "+");
for (int i = 1; i < 3; i++) {
msgBuffer.insert(12 - i * 2, ":");
}
msgBuffer.insert(6, " ");//設置日期與時間之間的連字符號
for (int i = 1; i < 3; i++) {
msgBuffer.insert(6 - i * 2, "-");//設置年、月、日之間的連字符號
}
return (new String(msgBuffer));
}
//*****************************************************************
//*****************************************************************
//修正號碼在內存中的表示,每2位爲1組,每組2個數字交換,
//若號碼個數爲奇數,則在末尾補'F'湊成偶數,然後再進行變換,
//因爲在計算機中,表示數字高低位順序與我們的習慣相反.
//如:"8613851872468" --> "683158812764F8"
public String changePhoneNumber(String phoneNumber) {
int numberLength = phoneNumber.length();
if (phoneNumber.length() % 2 != 0) {
phoneNumber = phoneNumber + "F";
numberLength += 1;
}
char newPhoneNumber[] = new char[numberLength];
for (int i = 0; i < numberLength; i += 2) {
newPhoneNumber[i] = phoneNumber.charAt(i + 1);
newPhoneNumber[i + 1] = phoneNumber.charAt(i);
}
return (new String(newPhoneNumber));
}
//*****************************************************************
//*****************************************************************
//轉換爲UNICODE編碼
public String asc2unicode(StringBuffer msgString) {
StringBuffer msgReturn = new StringBuffer();
int msgLength = msgString.length();
if (msgLength > 0) {
for (int i = 0; i < msgLength; i++) {
new Integer((int) msgString.charAt(0)).toString();
msgReturn.append(new StringBuffer());
String msgCheck = new String(Integer
.toHexString((int) msgString.charAt(i)));
if (msgCheck.length() < 4) {
msgCheck = "00" + msgCheck;
}
msgReturn.append(new StringBuffer(msgCheck));
}
}
return (new String(msgReturn).toUpperCase());
}
//*****************************************************************
//*****************************************************************
//UNICODE編碼轉換爲正常文字
public String unicode2asc(String msgString) {
int msgLength = msgString.length();
char msg[] = new char[msgLength / 4];
for (int i = 0; i < msgLength / 4; i++) {
//UNICODE編碼轉成十六進制數,再轉換爲正常文字
msg[i] = (char) Integer.parseInt((msgString.substring(i * 4,
4 * i + 4)), 16);
}
return (new String(msg));
}
//*****************************************************************
//*****************************************************************
//不斷讀取返回信號,當收到OK信號時,停止讀取,以執行下面的操作
public void getReply() {
this.replyString = readFromSerialPort(this.message);
while (this.replyString != null) {
if (this.replyString.equals("OK")
|| this.replyString.equals("ERROR"))
return;
waitForRead(this.getReplyInterval);
this.replyString = readFromSerialPort(this.message);
}
}
//*****************************************************************
//*****************************************************************
//檢查GSM Modem或卡有無連接錯誤
public void checkConn() {
if (this.errFlag == true)
return;
this.message = "";
writeToSerialPort("AT+CSCA?/r");
waitForRead(this.commandDelay);
getReply();
if (this.replyString.equals("ERROR")) {
returnStateInfo("Modem 或手機卡連接有誤,請檢查!");
this.errFlag = true;
closeIOStream();
closeSerialPort();
return;
}
returnStateInfo("連接正常!");
}
//*****************************************************************
//*****************************************************************
//刪除短信
public void delMessage(int msgIndex) {
this.message = "";
getSerialPort();
listenSerialPort();
checkConn();
writeToSerialPort("AT+CMGF=0/r");
waitForRead(this.commandDelay);
getReply();
if (this.replyString.equals("OK")) {
this.message = "";
try {
writeToSerialPort("AT+CMGD=" + msgIndex + "/r");
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
closeIOStream();
closeSerialPort();
}
//*****************************************************************
private void returnStateInfo(String errInfo) {
System.out.println(errInfo);
}
}
裏面要用到的包我就不列了,自己看着下吧.還有個讀寫XML文件的類,我前面的文章裏有了.
下面是測試用的代碼:(需要短信Modem)
/*
* Created on 2005-4-18 11:23:57
*
*/
/**
* @author zxub
*
*/
public class test {
public static void main(String[] args) {
CommConnection ccon=new CommConnection();
ccon.sendmsg("測試!","132XXXXXXXX");
//ccon.readMessage(3);
//ccon.delMessage(39);
//ccon.readAllMessage(4);
}
}