java寫的關於串口收發短信的東東[原創]

  前段時間,網絡不好,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);     
 }  
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章