SMSLib实现Java短信收发的功能

     blog迁移至: http://www.micmiu.com 

    用java实现短信收发的功能,目前一般项目中短信群发功能的实现方法大致有下面三种: 
  • 1、 向运行商申请短信网关,不需要额外的设备,利用运行商提供的API调用程序发送短信,适用于大型的通信公司。
  • 2、 借助像GSM MODEM之类的设备(支持AT指令的手机也行),通过数据线连接电脑来发送短信,这种方法比较适用于小公司及个人。要实现这种方式必须理解串口通信、AT指令、短信编码、解码。
  • 3、 借助第三方运行的网站实现,由网站代发短信数据,这种方法对网站依赖性太高,对网络的要求也比较高。

        鉴于项目的情况和多方考虑,同时又找到了一个开源的SMSLib项目的支持,比较倾向于第二种方法,SMSLib的出现就不需要我们自己去写底层的AT指令,这样就可以直接通过调用SMSLib的API来实现通过GSM modem来收发送短信了。 

SMSLib官方网站:http://smslib.org/,使用SMSLib的一些基本要点: 
  • SUN JDK 1.6 or newer. (Java环境)
  • Java Communications Library. (Java串口通信)
  • Apache ANT for building the sources. (编译源码时需要的)
  • Apache log4j. (日志工具)
  • Apache Jakarta Commons - NET. (网络操作相关的)
  • JSMPP Library (SMPP协议时需要的)

有关Java串口通信需要补充说明: 

附件提供相关下载: 

本次测试的环境是window,GSM modem是wavecom,所以这次主要描述window环境下简单的实现过程: 
【一】、配置相应的环境 
      首先解压下载的Java Comm v2文件javacomm20-win32.zip,具体配置步骤如下: 
  • 把文件:comm.jar copy 到目录:<JDKDIR>/jre/lib/ext/,当然这一步也可以不要这样做,你只需把comm.jar copy到所要运行的项目对应的lib/下既可
  • 把文件:javax.comm.properties copy 到目录:<JDKDIR>/jre/lib/
  • 把DLL文件:win32com.dll(windows) copy 到目录:<JDKDIR>/jre/bin/
  • 如果存在JRE目录, 最好按照上面步骤把文件copy到<JREDIR>相应的目录下

【二】、测试串口端口程序: 
TestGetPortList.java 
Java代码   收藏代码
  1. package michael.comm.serial;  
  2.   
  3. import java.util.Enumeration;  
  4.   
  5. import javax.comm.CommDriver;  
  6. import javax.comm.CommPortIdentifier;  
  7. import javax.comm.SerialPort;  
  8.   
  9. /** 
  10.  * @author michael 
  11.  *  
  12.  */  
  13. public class TestGetPortList {  
  14.   
  15.     /** 
  16.      * @param args 
  17.      * @throws Exception 
  18.      */  
  19.     public static void main(String[] args) throws Exception {  
  20.         // 人工加载驱动  
  21.         // MainTest.driverInit();  
  22.         TestGetPortList.getCommPortList();  
  23.         // 人工加载驱动获取端口列表  
  24.         // TestGetPortList.getPortByDriver();  
  25.   
  26.     }  
  27.   
  28.     /** 
  29.      * 手工加载驱动<br> 
  30.      * 正常情况下程序会自动加载驱动,故通常不需要人工加载<br> 
  31.      * 每重复加载一次,会把端口重复注册,CommPortIdentifier.getPortIdentifiers()获取的端口就会重复 
  32.      */  
  33.     public static void driverManualInit() {  
  34.         String driverName = "com.sun.comm.Win32Driver";  
  35.         String libname = "win32com";  
  36.         CommDriver commDriver = null;  
  37.         try {  
  38.             System.loadLibrary("win32com");  
  39.             System.out.println(libname + " Library Loaded");  
  40.   
  41.             commDriver = (javax.comm.CommDriver) Class.forName(driverName)  
  42.                     .newInstance();  
  43.             commDriver.initialize();  
  44.             System.out.println("comm Driver Initialized");  
  45.   
  46.         } catch (Exception e) {  
  47.             System.err.println(e);  
  48.         }  
  49.     }  
  50.   
  51.     /** 
  52.      * 获取端口列表 
  53.      */  
  54.     public static void getCommPortList() {  
  55.         CommPortIdentifier portId;  
  56.         Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();  
  57.         while (portEnum.hasMoreElements()) {  
  58.             portId = (CommPortIdentifier) portEnum.nextElement();  
  59.   
  60.             if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {  
  61.                 System.out.println("串口: name-" + portId.getName()  
  62.                         + " 是否占用-" + portId.isCurrentlyOwned());  
  63.             } else {  
  64.                 System.out.println("并口: name-" + portId.getName()  
  65.                         + " 是否占用-" + portId.isCurrentlyOwned());  
  66.             }  
  67.         }  
  68.         System.out.println("-------------------------------------");  
  69.     }  
  70.   
  71.     /** 
  72.      *  
  73.      */  
  74.     public static void getPortByDriver() {  
  75.   
  76.         String driverName = "com.sun.comm.Win32Driver";  
  77.         String libname = "win32com";  
  78.         CommDriver commDriver = null;  
  79.         try {  
  80.             System.loadLibrary("win32com");  
  81.             System.out.println(libname + " Library Loaded");  
  82.   
  83.             commDriver = (CommDriver) Class.forName(driverName).newInstance();  
  84.             commDriver.initialize();  
  85.             System.out.println("comm Driver Initialized");  
  86.   
  87.         } catch (Exception e) {  
  88.             System.err.println(e);  
  89.         }  
  90.         SerialPort sPort = null;  
  91.         try {  
  92.   
  93.             sPort = (SerialPort) commDriver.getCommPort("COM24",  
  94.                     CommPortIdentifier.PORT_SERIAL);  
  95.             System.out.println("find CommPort:" + sPort.toString());  
  96.         } catch (Exception e) {  
  97.             System.out.println(e.getMessage());  
  98.         }  
  99.   
  100.     }  
  101.   
  102. }  

本机运行结果:
引用

串口: name-COM10 是否占用-false 
串口: name-COM21 是否占用-false 
串口: name-COM23 是否占用-false 
串口: name-COM20 是否占用-false 
串口: name-COM22 是否占用-false 
串口: name-COM24 是否占用-false 
串口: name-COM9 是否占用-false 
串口: name-COM19 是否占用-false 
串口: name-COM3 是否占用-false 
串口: name-COM8 是否占用-false 
串口: name-COM98 是否占用-false 
串口: name-COM99 是否占用-false 
串口: name-COM4 是否占用-false 
串口: name-COM5 是否占用-false 
串口: name-COM6 是否占用-false 
并口: name-LPT1 是否占用-false 
并口: name-LPT2 是否占用-false 
------------------------------------- 

【三】、检查串口设备信息: 
TestCommPort.java 
Java代码   收藏代码
  1. package michael.comm.serial;  
  2.   
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.util.Enumeration;  
  6.   
  7. import javax.comm.CommPortIdentifier;  
  8. import javax.comm.SerialPort;  
  9.   
  10. /** 
  11.  * @author michael 
  12.  *  
  13.  */  
  14. public class TestCommPort {  
  15.     static CommPortIdentifier portId;  
  16.     static Enumeration portList;  
  17.     static int bauds[] = { 96001920057600115200 };  
  18.   
  19.     /** 
  20.      * @param args 
  21.      */  
  22.     public static void main(String[] args) {  
  23.         portList = CommPortIdentifier.getPortIdentifiers();  
  24.         System.out.println("GSM Modem 串行端口连接测试开始...");  
  25.         String portName = "COM24";  
  26.         while (portList.hasMoreElements()) {  
  27.             portId = (CommPortIdentifier) portList.nextElement();  
  28.             if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL  
  29.                     && portName.equals(portId.getName())) {  
  30.                 System.out.println("找到串口: " + portId.getName());  
  31.                 for (int i = 0; i < bauds.length; i++) {  
  32.                     System.out.print("  Trying at " + bauds[i] + "...");  
  33.                     try {  
  34.                         SerialPort serialPort;  
  35.                         InputStream inStream;  
  36.                         OutputStream outStream;  
  37.                         int c;  
  38.                         StringBuffer response = new StringBuffer();  
  39.                         serialPort = (SerialPort) portId.open(  
  40.                                 "SMSLibCommTester"2000);  
  41.                         serialPort  
  42.                                 .setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);  
  43.                         serialPort.setSerialPortParams(bauds[i],  
  44.                                 SerialPort.DATABITS_8, SerialPort.STOPBITS_1,  
  45.                                 SerialPort.PARITY_NONE);  
  46.                         inStream = serialPort.getInputStream();  
  47.                         outStream = serialPort.getOutputStream();  
  48.                         serialPort.enableReceiveTimeout(1000);  
  49.                         c = inStream.read();  
  50.                         while (c != -1) {  
  51.                             c = inStream.read();  
  52.                         }  
  53.                         outStream.write('A');  
  54.                         outStream.write('T');  
  55.                         outStream.write('\r');  
  56.                         try {  
  57.                             Thread.sleep(1000);  
  58.                         } catch (Exception e) {  
  59.                         }  
  60.                         c = inStream.read();  
  61.                         while (c != -1) {  
  62.                             response.append((char) c);  
  63.                             c = inStream.read();  
  64.                         }  
  65.                         if (response.indexOf("OK") >= 0) {  
  66.                             System.out.print("  正在检测设备:");  
  67.                             try {  
  68.                                 outStream.write('A');  
  69.                                 outStream.write('T');  
  70.                                 outStream.write('+');  
  71.                                 outStream.write('C');  
  72.                                 outStream.write('G');  
  73.                                 outStream.write('M');  
  74.                                 outStream.write('M');  
  75.                                 outStream.write('\r');  
  76.                                 response = new StringBuffer();  
  77.                                 c = inStream.read();  
  78.                                 while (c != -1) {  
  79.                                     response.append((char) c);  
  80.                                     c = inStream.read();  
  81.                                 }  
  82.                                 System.out.println("  发现设备: "  
  83.                                         + response.toString().replaceAll(  
  84.                                                 "(\\s+OK\\s+)|[\n\r]"""));  
  85.                             } catch (Exception e) {  
  86.                                 System.out.println("  检测设备失败,获取设备信息异常:"  
  87.                                         + e.getMessage());  
  88.                             }  
  89.                         } else {  
  90.                             System.out.println("  检测设备失败,沒有接收到响应结果!");  
  91.                         }  
  92.                         serialPort.close();  
  93.                     } catch (Exception e) {  
  94.                         System.out.println("  检测设备失败,发生异常:" + e.getMessage());  
  95.                     }  
  96.                 }  
  97.             }  
  98.         }  
  99.     }  
  100. }  

运行结果如下: 
引用

GSM Modem 串行端口连接测试开始... 
找到串口: COM24 
  Trying at 9600...  正在检测设备:  发现设备: AT+CGMM MULTIBAND  900E  1800 
  Trying at 19200...  发现设备失败,沒有接收到响应结果! 
  Trying at 57600...  发现设备失败,沒有接收到响应结果! 
  Trying at 115200...  发现设备失败,沒有接收到响应结果! 


【四】、测试收发短信: 
Java代码   收藏代码
  1. package michael.sms;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.LinkedList;  
  5. import java.util.List;  
  6.   
  7. import org.apache.log4j.Level;  
  8. import org.apache.log4j.Logger;  
  9. import org.smslib.AGateway;  
  10. import org.smslib.GatewayException;  
  11. import org.smslib.InboundMessage;  
  12. import org.smslib.OutboundMessage;  
  13. import org.smslib.Service;  
  14. import org.smslib.AGateway.Protocols;  
  15. import org.smslib.Message.MessageEncodings;  
  16. import org.smslib.modem.SerialModemGateway;  
  17.   
  18. /** 
  19.  * @author michael 
  20.  *  
  21.  */  
  22. public class SmsHandler {  
  23.     private static final Logger logger = Logger.getLogger(SmsHandler.class);  
  24.   
  25.     private Service smsService;  
  26.   
  27.     /** 
  28.      *  
  29.      */  
  30.     public SmsHandler() {  
  31.         smsService = Service.getInstance();  
  32.         List<AGateway> agatewayList = new ArrayList<AGateway>();  
  33.   
  34.         String portName = "COM24";//"/dev/ttyUSB0";// COM24  
  35.         SerialModemGateway gateway = new SerialModemGateway(  
  36.                 "modem." + portName, portName, 9600"wavecom""PL2303");  
  37.         gateway.setInbound(true);  
  38.         gateway.setOutbound(true);  
  39.         gateway.setProtocol(Protocols.PDU);  
  40.         gateway.setSimPin("0000");  
  41.         agatewayList.add(gateway);  
  42.         try {  
  43.             for (AGateway gatewayTmp : agatewayList) {  
  44.                 smsService.addGateway(gatewayTmp);  
  45.             }  
  46.         } catch (GatewayException ex) {  
  47.             logger.error(ex.getMessage());  
  48.         }  
  49.     }  
  50.   
  51.     /** 
  52.      *  
  53.      */  
  54.     public void start() {  
  55.         logger.info("SMS service start.....");  
  56.         try {  
  57.             smsService.startService();  
  58.         } catch (Exception ex) {  
  59.             logger.error("SMS service start error:", ex);  
  60.         }  
  61.     }  
  62.   
  63.     /** 
  64.      *  
  65.      */  
  66.     public void destroy() {  
  67.         try {  
  68.             smsService.stopService();  
  69.         } catch (Exception ex) {  
  70.             logger.error("SMS service stop error:", ex);  
  71.         }  
  72.         logger.info("SMS service stop");  
  73.     }  
  74.   
  75.     /** 
  76.      * send SMS 
  77.      * @param msg 
  78.      * @return Boolean 
  79.      */  
  80.     public Boolean sendSMS(OutboundMessage msg) {  
  81.         try {  
  82.             msg.setEncoding(MessageEncodings.ENCUCS2);  
  83.             return smsService.sendMessage(msg);  
  84.         } catch (Exception e) {  
  85.             logger.error("send error:", e);  
  86.         }  
  87.         return false;  
  88.     }  
  89.   
  90.     private boolean isStarted() {  
  91.         if (smsService.getServiceStatus() == Service.ServiceStatus.STARTED) {  
  92.             for (AGateway gateway : smsService.getGateways()) {  
  93.                 if (gateway.getStatus() == AGateway.GatewayStatuses.STARTED) {  
  94.                     return true;  
  95.                 }  
  96.             }  
  97.         }  
  98.         return false;  
  99.     }  
  100.   
  101.     /** 
  102.      * read SMS 
  103.      * @return List 
  104.      */  
  105.     public List<InboundMessage> readSMS() {  
  106.         List<InboundMessage> msgList = new LinkedList<InboundMessage>();  
  107.         if (!isStarted()) {  
  108.             return msgList;  
  109.         }  
  110.         try {  
  111.             this.smsService.readMessages(msgList,  
  112.                     InboundMessage.MessageClasses.ALL);  
  113.             logger.info("read SMS size: " + msgList.size());  
  114.         } catch (Exception e) {  
  115.             logger.error("read error:", e);  
  116.         }  
  117.         return msgList;  
  118.     }  
  119.   
  120.     /** 
  121.      * @param args 
  122.      */  
  123.     public static void main(String[] args) {  
  124.         Logger.getRootLogger().setLevel(Level.INFO);  
  125.         OutboundMessage outMsg = new OutboundMessage("189xxxx****""信息测试");  
  126.         SmsHandler smsHandler = new SmsHandler();  
  127.         smsHandler.start();  
  128.         //发送短信  
  129.         smsHandler.sendSMS(outMsg);  
  130.         //读取短信  
  131.         List<InboundMessage> readList = smsHandler.readSMS();  
  132.         for (InboundMessage in : readList) {  
  133.             System.out.println("发信人:" + in.getOriginator() + " 短信内容:"  
  134.                     + in.getText());  
  135.         }  
  136.         smsHandler.destroy();  
  137.         System.out.println("-----------");  
  138.     }  
  139.   
  140. }  

发送短信亲测,手机能正常接收显示。读取设备的短信程序运行结果结果如下: 
引用

INFO - Service.listSystemInformation(113) | SMSLib: A Java API library for sending and receiving SMS via a GSM modem or other supported gateways. 
This software is distributed under the terms of the Apache v2.0 License. 
Web Site: http://smslib.org 
INFO - Service.listSystemInformation(114) | Version: 3.5.1 
INFO - Service.listSystemInformation(115) | JRE Version: 1.6.0_18 
INFO - Service.listSystemInformation(116) | JRE Impl Version: 16.0-b13 
INFO - Service.listSystemInformation(117) | O/S: Windows Vista / x86 / 6.0 
INFO - SmsHandler.start(55) | SMS service start..... 
INFO - DefaultQueueManager.init(92) | Queue directory not defined. Queued messages will not be saved to filesystem. 
INFO - ModemGateway.startGateway(188) | GTW: modem.COM24: Starting gateway, using Generic AT Handler. 
INFO - SerialModemDriver.connectPort(68) | GTW: modem.COM24: Opening: COM24 @9600 
INFO - AModemDriver.waitForNetworkRegistration(459) | GTW: modem.COM24: GSM: Registered to foreign network (roaming). 
INFO - AModemDriver.connect(175) | GTW: modem.COM24: MEM: Storage Locations Found: SMBM 
INFO - CNMIDetector.getBestMatch(142) | CNMI: No best match, returning: 1 
INFO - ModemGateway.startGateway(191) | GTW: modem.COM24: Gateway started. 
INFO - SmsHandler.readSMS(113) | read SMS size: 1 
发信人:8618918001030 短信内容:hello 回复测试
 
INFO - ModemGateway.stopGateway(197) | GTW: modem.COM24: Stopping gateway... 
INFO - SerialModemDriver.disconnectPort(120) | GTW: modem.COM24: Closing: COM24 @9600 
INFO - ModemGateway.stopGateway(201) | GTW: modem.COM24: Gateway stopped. 
INFO - SmsHandler.destroy(72) | SMS service stop 
----------- 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值