`
阿尔萨斯
  • 浏览: 4180705 次
社区版块
存档分类
最新评论

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. packagemichael.comm.serial;
  2. importjava.util.Enumeration;
  3. importjavax.comm.CommDriver;
  4. importjavax.comm.CommPortIdentifier;
  5. importjavax.comm.SerialPort;
  6. /**
  7. *@authormichael
  8. *
  9. */
  10. publicclassTestGetPortList{
  11. /**
  12. *@paramargs
  13. *@throwsException
  14. */
  15. publicstaticvoidmain(String[]args)throwsException{
  16. //人工加载驱动
  17. //MainTest.driverInit();
  18. TestGetPortList.getCommPortList();
  19. //人工加载驱动获取端口列表
  20. //TestGetPortList.getPortByDriver();
  21. }
  22. /**
  23. *手工加载驱动<br>
  24. *正常情况下程序会自动加载驱动,故通常不需要人工加载<br>
  25. *每重复加载一次,会把端口重复注册,CommPortIdentifier.getPortIdentifiers()获取的端口就会重复
  26. */
  27. publicstaticvoiddriverManualInit(){
  28. StringdriverName="com.sun.comm.Win32Driver";
  29. Stringlibname="win32com";
  30. CommDrivercommDriver=null;
  31. try{
  32. System.loadLibrary("win32com");
  33. System.out.println(libname+"LibraryLoaded");
  34. commDriver=(javax.comm.CommDriver)Class.forName(driverName)
  35. .newInstance();
  36. commDriver.initialize();
  37. System.out.println("commDriverInitialized");
  38. }catch(Exceptione){
  39. System.err.println(e);
  40. }
  41. }
  42. /**
  43. *获取端口列表
  44. */
  45. publicstaticvoidgetCommPortList(){
  46. CommPortIdentifierportId;
  47. EnumerationportEnum=CommPortIdentifier.getPortIdentifiers();
  48. while(portEnum.hasMoreElements()){
  49. portId=(CommPortIdentifier)portEnum.nextElement();
  50. if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL){
  51. System.out.println("串口:name-"+portId.getName()
  52. +"是否占用-"+portId.isCurrentlyOwned());
  53. }else{
  54. System.out.println("并口:name-"+portId.getName()
  55. +"是否占用-"+portId.isCurrentlyOwned());
  56. }
  57. }
  58. System.out.println("-------------------------------------");
  59. }
  60. /**
  61. *
  62. */
  63. publicstaticvoidgetPortByDriver(){
  64. StringdriverName="com.sun.comm.Win32Driver";
  65. Stringlibname="win32com";
  66. CommDrivercommDriver=null;
  67. try{
  68. System.loadLibrary("win32com");
  69. System.out.println(libname+"LibraryLoaded");
  70. commDriver=(CommDriver)Class.forName(driverName).newInstance();
  71. commDriver.initialize();
  72. System.out.println("commDriverInitialized");
  73. }catch(Exceptione){
  74. System.err.println(e);
  75. }
  76. SerialPortsPort=null;
  77. try{
  78. sPort=(SerialPort)commDriver.getCommPort("COM24",
  79. CommPortIdentifier.PORT_SERIAL);
  80. System.out.println("findCommPort:"+sPort.toString());
  81. }catch(Exceptione){
  82. System.out.println(e.getMessage());
  83. }
  84. }
  85. }

本机运行结果:
引用

串口: 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. packagemichael.comm.serial;
  2. importjava.io.InputStream;
  3. importjava.io.OutputStream;
  4. importjava.util.Enumeration;
  5. importjavax.comm.CommPortIdentifier;
  6. importjavax.comm.SerialPort;
  7. /**
  8. *@authormichael
  9. *
  10. */
  11. publicclassTestCommPort{
  12. staticCommPortIdentifierportId;
  13. staticEnumerationportList;
  14. staticintbauds[]={9600,19200,57600,115200};
  15. /**
  16. *@paramargs
  17. */
  18. publicstaticvoidmain(String[]args){
  19. portList=CommPortIdentifier.getPortIdentifiers();
  20. System.out.println("GSMModem串行端口连接测试开始...");
  21. StringportName="COM24";
  22. while(portList.hasMoreElements()){
  23. portId=(CommPortIdentifier)portList.nextElement();
  24. if(portId.getPortType()==CommPortIdentifier.PORT_SERIAL
  25. &&portName.equals(portId.getName())){
  26. System.out.println("找到串口:"+portId.getName());
  27. for(inti=0;i<bauds.length;i++){
  28. System.out.print("Tryingat"+bauds[i]+"...");
  29. try{
  30. SerialPortserialPort;
  31. InputStreaminStream;
  32. OutputStreamoutStream;
  33. intc;
  34. StringBufferresponse=newStringBuffer();
  35. serialPort=(SerialPort)portId.open(
  36. "SMSLibCommTester",2000);
  37. serialPort
  38. .setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);
  39. serialPort.setSerialPortParams(bauds[i],
  40. SerialPort.DATABITS_8,SerialPort.STOPBITS_1,
  41. SerialPort.PARITY_NONE);
  42. inStream=serialPort.getInputStream();
  43. outStream=serialPort.getOutputStream();
  44. serialPort.enableReceiveTimeout(1000);
  45. c=inStream.read();
  46. while(c!=-1){
  47. c=inStream.read();
  48. }
  49. outStream.write('A');
  50. outStream.write('T');
  51. outStream.write('\r');
  52. try{
  53. Thread.sleep(1000);
  54. }catch(Exceptione){
  55. }
  56. c=inStream.read();
  57. while(c!=-1){
  58. response.append((char)c);
  59. c=inStream.read();
  60. }
  61. if(response.indexOf("OK")>=0){
  62. System.out.print("正在检测设备:");
  63. try{
  64. outStream.write('A');
  65. outStream.write('T');
  66. outStream.write('+');
  67. outStream.write('C');
  68. outStream.write('G');
  69. outStream.write('M');
  70. outStream.write('M');
  71. outStream.write('\r');
  72. response=newStringBuffer();
  73. c=inStream.read();
  74. while(c!=-1){
  75. response.append((char)c);
  76. c=inStream.read();
  77. }
  78. System.out.println("发现设备:"
  79. +response.toString().replaceAll(
  80. "(\\s+OK\\s+)|[\n\r]",""));
  81. }catch(Exceptione){
  82. System.out.println("检测设备失败,获取设备信息异常:"
  83. +e.getMessage());
  84. }
  85. }else{
  86. System.out.println("检测设备失败,沒有接收到响应结果!");
  87. }
  88. serialPort.close();
  89. }catch(Exceptione){
  90. System.out.println("检测设备失败,发生异常:"+e.getMessage());
  91. }
  92. }
  93. }
  94. }
  95. }
  96. }

运行结果如下:
引用

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


【四】、测试收发短信:
Java代码收藏代码
  1. packagemichael.sms;
  2. importjava.util.ArrayList;
  3. importjava.util.LinkedList;
  4. importjava.util.List;
  5. importorg.apache.log4j.Level;
  6. importorg.apache.log4j.Logger;
  7. importorg.smslib.AGateway;
  8. importorg.smslib.GatewayException;
  9. importorg.smslib.InboundMessage;
  10. importorg.smslib.OutboundMessage;
  11. importorg.smslib.Service;
  12. importorg.smslib.AGateway.Protocols;
  13. importorg.smslib.Message.MessageEncodings;
  14. importorg.smslib.modem.SerialModemGateway;
  15. /**
  16. *@authormichael
  17. *
  18. */
  19. publicclassSmsHandler{
  20. privatestaticfinalLoggerlogger=Logger.getLogger(SmsHandler.class);
  21. privateServicesmsService;
  22. /**
  23. *
  24. */
  25. publicSmsHandler(){
  26. smsService=Service.getInstance();
  27. List<AGateway>agatewayList=newArrayList<AGateway>();
  28. StringportName="COM24";//"/dev/ttyUSB0";//COM24
  29. SerialModemGatewaygateway=newSerialModemGateway(
  30. "modem."+portName,portName,9600,"wavecom","PL2303");
  31. gateway.setInbound(true);
  32. gateway.setOutbound(true);
  33. gateway.setProtocol(Protocols.PDU);
  34. gateway.setSimPin("0000");
  35. agatewayList.add(gateway);
  36. try{
  37. for(AGatewaygatewayTmp:agatewayList){
  38. smsService.addGateway(gatewayTmp);
  39. }
  40. }catch(GatewayExceptionex){
  41. logger.error(ex.getMessage());
  42. }
  43. }
  44. /**
  45. *
  46. */
  47. publicvoidstart(){
  48. logger.info("SMSservicestart.....");
  49. try{
  50. smsService.startService();
  51. }catch(Exceptionex){
  52. logger.error("SMSservicestarterror:",ex);
  53. }
  54. }
  55. /**
  56. *
  57. */
  58. publicvoiddestroy(){
  59. try{
  60. smsService.stopService();
  61. }catch(Exceptionex){
  62. logger.error("SMSservicestoperror:",ex);
  63. }
  64. logger.info("SMSservicestop");
  65. }
  66. /**
  67. *sendSMS
  68. *@parammsg
  69. *@returnBoolean
  70. */
  71. publicBooleansendSMS(OutboundMessagemsg){
  72. try{
  73. msg.setEncoding(MessageEncodings.ENCUCS2);
  74. returnsmsService.sendMessage(msg);
  75. }catch(Exceptione){
  76. logger.error("senderror:",e);
  77. }
  78. returnfalse;
  79. }
  80. privatebooleanisStarted(){
  81. if(smsService.getServiceStatus()==Service.ServiceStatus.STARTED){
  82. for(AGatewaygateway:smsService.getGateways()){
  83. if(gateway.getStatus()==AGateway.GatewayStatuses.STARTED){
  84. returntrue;
  85. }
  86. }
  87. }
  88. returnfalse;
  89. }
  90. /**
  91. *readSMS
  92. *@returnList
  93. */
  94. publicList<InboundMessage>readSMS(){
  95. List<InboundMessage>msgList=newLinkedList<InboundMessage>();
  96. if(!isStarted()){
  97. returnmsgList;
  98. }
  99. try{
  100. this.smsService.readMessages(msgList,
  101. InboundMessage.MessageClasses.ALL);
  102. logger.info("readSMSsize:"+msgList.size());
  103. }catch(Exceptione){
  104. logger.error("readerror:",e);
  105. }
  106. returnmsgList;
  107. }
  108. /**
  109. *@paramargs
  110. */
  111. publicstaticvoidmain(String[]args){
  112. Logger.getRootLogger().setLevel(Level.INFO);
  113. OutboundMessageoutMsg=newOutboundMessage("189xxxx****","信息测试");
  114. SmsHandlersmsHandler=newSmsHandler();
  115. smsHandler.start();
  116. //发送短信
  117. smsHandler.sendSMS(outMsg);
  118. //读取短信
  119. List<InboundMessage>readList=smsHandler.readSMS();
  120. for(InboundMessagein:readList){
  121. System.out.println("发信人:"+in.getOriginator()+"短信内容:"
  122. +in.getText());
  123. }
  124. smsHandler.destroy();
  125. System.out.println("-----------");
  126. }
  127. }

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

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
-----------

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics