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系统可以用SUN Java Comm v2. (该版本好像也支持solaris)         其下载地址:http://smslib.googlecode.com/files/javacomm20-win32.zip
  • 其他操作系统(比如:Linux, Unix, BSD,等等),你可以选择 Java Comm v3 或者是RxTx。         Java Comm v3下载地址:http://java.sun.com/products/javacomm/(需要注册);
             RxTx官网:http://users.frii.com/jarvi/rxtx/index.html or http://rxtx.qbang.org/wiki/index.php/Main_Page

附件提供相关下载:

  • java串口通信v2:javacomm20-win32.zip
  • smslib-3.5.1.jar
  • 短信 modem驱动:PL2303_Prolific_DriverInstaller_v130.zip

本次测试的环境是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. import java.util.Enumeration;
  3. import javax.comm.CommDriver;
  4. import javax.comm.CommPortIdentifier;
  5. import javax.comm.SerialPort;
  6. /**
  7. * @author michael
  8. *
  9. */
  10. public class TestGetPortList {
  11. /**
  12. * @param args
  13. * @throws Exception
  14. */
  15. public static void main(String[] args) throws Exception {
  16. // 人工加载驱动
  17. // MainTest.driverInit();
  18. TestGetPortList.getCommPortList();
  19. // 人工加载驱动获取端口列表
  20. // TestGetPortList.getPortByDriver();
  21. }
  22. /**
  23. * 手工加载驱动<br>
  24. * 正常情况下程序会自动加载驱动,故通常不需要人工加载<br>
  25. * 每重复加载一次,会把端口重复注册,CommPortIdentifier.getPortIdentifiers()获取的端口就会重复
  26. */
  27. public static void driverManualInit() {
  28. String driverName = "com.sun.comm.Win32Driver";
  29. String libname = "win32com";
  30. CommDriver commDriver = null;
  31. try {
  32. System.loadLibrary("win32com");
  33. System.out.println(libname + " Library Loaded");
  34. commDriver = (javax.comm.CommDriver) Class.forName(driverName)
  35. .newInstance();
  36. commDriver.initialize();
  37. System.out.println("comm Driver Initialized");
  38. } catch (Exception e) {
  39. System.err.println(e);
  40. }
  41. }
  42. /**
  43. * 获取端口列表
  44. */
  45. public static void getCommPortList() {
  46. CommPortIdentifier portId;
  47. Enumeration portEnum = 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. public static void getPortByDriver() {
  64. String driverName = "com.sun.comm.Win32Driver";
  65. String libname = "win32com";
  66. CommDriver commDriver = null;
  67. try {
  68. System.loadLibrary("win32com");
  69. System.out.println(libname + " Library Loaded");
  70. commDriver = (CommDriver) Class.forName(driverName).newInstance();
  71. commDriver.initialize();
  72. System.out.println("comm Driver Initialized");
  73. } catch (Exception e) {
  74. System.err.println(e);
  75. }
  76. SerialPort sPort = null;
  77. try {
  78. sPort = (SerialPort) commDriver.getCommPort("COM24",
  79. CommPortIdentifier.PORT_SERIAL);
  80. System.out.println("find CommPort:" + sPort.toString());
  81. } catch (Exception e) {
  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. package michael.comm.serial;
  2. import java.io.InputStream;
  3. import java.io.OutputStream;
  4. import java.util.Enumeration;
  5. import javax.comm.CommPortIdentifier;
  6. import javax.comm.SerialPort;
  7. /**
  8. * @author michael
  9. *
  10. */
  11. public class TestCommPort {
  12. static CommPortIdentifier portId;
  13. static Enumeration portList;
  14. static int bauds[] = { 9600, 19200, 57600, 115200 };
  15. /**
  16. * @param args
  17. */
  18. public static void main(String[] args) {
  19. portList = CommPortIdentifier.getPortIdentifiers();
  20. System.out.println("GSM Modem 串行端口连接测试开始...");
  21. String portName = "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 (int i = 0; i < bauds.length; i++) {
  28. System.out.print("  Trying at " + bauds[i] + "...");
  29. try {
  30. SerialPort serialPort;
  31. InputStream inStream;
  32. OutputStream outStream;
  33. int c;
  34. StringBuffer response = new StringBuffer();
  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 (Exception e) {
  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 = new StringBuffer();
  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 (Exception e) {
  82. System.out.println("  检测设备失败,获取设备信息异常:"
  83. + e.getMessage());
  84. }
  85. } else {
  86. System.out.println("  检测设备失败,沒有接收到响应结果!");
  87. }
  88. serialPort.close();
  89. } catch (Exception e) {
  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. package michael.sms;
  2. import java.util.ArrayList;
  3. import java.util.LinkedList;
  4. import java.util.List;
  5. import org.apache.log4j.Level;
  6. import org.apache.log4j.Logger;
  7. import org.smslib.AGateway;
  8. import org.smslib.GatewayException;
  9. import org.smslib.InboundMessage;
  10. import org.smslib.OutboundMessage;
  11. import org.smslib.Service;
  12. import org.smslib.AGateway.Protocols;
  13. import org.smslib.Message.MessageEncodings;
  14. import org.smslib.modem.SerialModemGateway;
  15. /**
  16. * @author michael
  17. *
  18. */
  19. public class SmsHandler {
  20. private static final Logger logger = Logger.getLogger(SmsHandler.class);
  21. private Service smsService;
  22. /**
  23. *
  24. */
  25. public SmsHandler() {
  26. smsService = Service.getInstance();
  27. List<AGateway> agatewayList = new ArrayList<AGateway>();
  28. String portName = "COM24";//"/dev/ttyUSB0";// COM24
  29. SerialModemGateway gateway = new SerialModemGateway(
  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 (AGateway gatewayTmp : agatewayList) {
  38. smsService.addGateway(gatewayTmp);
  39. }
  40. } catch (GatewayException ex) {
  41. logger.error(ex.getMessage());
  42. }
  43. }
  44. /**
  45. *
  46. */
  47. public void start() {
  48. logger.info("SMS service start.....");
  49. try {
  50. smsService.startService();
  51. } catch (Exception ex) {
  52. logger.error("SMS service start error:", ex);
  53. }
  54. }
  55. /**
  56. *
  57. */
  58. public void destroy() {
  59. try {
  60. smsService.stopService();
  61. } catch (Exception ex) {
  62. logger.error("SMS service stop error:", ex);
  63. }
  64. logger.info("SMS service stop");
  65. }
  66. /**
  67. * send SMS
  68. * @param msg
  69. * @return Boolean
  70. */
  71. public Boolean sendSMS(OutboundMessage msg) {
  72. try {
  73. msg.setEncoding(MessageEncodings.ENCUCS2);
  74. return smsService.sendMessage(msg);
  75. } catch (Exception e) {
  76. logger.error("send error:", e);
  77. }
  78. return false;
  79. }
  80. private boolean isStarted() {
  81. if (smsService.getServiceStatus() == Service.ServiceStatus.STARTED) {
  82. for (AGateway gateway : smsService.getGateways()) {
  83. if (gateway.getStatus() == AGateway.GatewayStatuses.STARTED) {
  84. return true;
  85. }
  86. }
  87. }
  88. return false;
  89. }
  90. /**
  91. * read SMS
  92. * @return List
  93. */
  94. public List<InboundMessage> readSMS() {
  95. List<InboundMessage> msgList = new LinkedList<InboundMessage>();
  96. if (!isStarted()) {
  97. return msgList;
  98. }
  99. try {
  100. this.smsService.readMessages(msgList,
  101. InboundMessage.MessageClasses.ALL);
  102. logger.info("read SMS size: " + msgList.size());
  103. } catch (Exception e) {
  104. logger.error("read error:", e);
  105. }
  106. return msgList;
  107. }
  108. /**
  109. * @param args
  110. */
  111. public static void main(String[] args) {
  112. Logger.getRootLogger().setLevel(Level.INFO);
  113. OutboundMessage outMsg = new OutboundMessage("189xxxx****", "信息测试");
  114. SmsHandler smsHandler = new SmsHandler();
  115. smsHandler.start();
  116. //发送短信
  117. smsHandler.sendSMS(outMsg);
  118. //读取短信
  119. List<InboundMessage> readList = smsHandler.readSMS();
  120. for (InboundMessage in : 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
-----------

-----------------------------------分 ------------------------------------隔 ------------------------------------线 --------------------------------------

SMSLib实现Java短信收发的功能相关推荐

  1. java 短信猫发送短信的方法

    http://zghbwjl.blog.163.com/blog/static/12033667220129175158806/ http://www.smscom.cn/sms_javasoft/ ...

  2. 超简单的java短信验证码,神级之作

    阿里云短信使用 -- 拓薪教育 短信猫:所谓短信猫,其实是一种用来收发短信的设备,他和我们用的手机一样,需要手机SIM卡的支持,在需要收发短信的时候,在短信猫里面插入一张我们平时用的手机卡,插上电源, ...

  3. java实现语音发送,Java实现发送手机短信语音验证功能代码实例

    这篇文章主要介绍了java实现发送手机短信语音验证功能代码实例,www.cppcns.com文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 利用第三方 ...

  4. java语音验证码_Java实现发送手机短信语音验证功能代码实例

    这篇文章主要介绍了Java实现发送手机短信语音验证功能代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 利用第三方平台可以实现发送手机短信验证 ...

  5. java短信验证码功能发送的验证码如何校验_Java实现发送短信验证码功能

    一个发送短信验证码的功能,使用的是信易通的短信平台接口,然后在Java中使用HttpClient模拟POST请求或者GET请求(看短信平台要求,一般的情况下都是POST请求),调用短信平台提供的接口( ...

  6. java 实现语音报警代码_Java实现发送手机短信语音验证功能代码实例

    这篇文章主要介绍了Java实现发送手机短信语音验证功能代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 利用第三方平台可以实现发送手机短信验证 ...

  7. 来电黑名单 java 软件,Android8.1 通过黑名单屏蔽系统短信和来电功能

    前言 同样的最近有个新需求,需要将8.1 设备的来电功能和短信功能都屏蔽掉,特殊产品就是特殊定制,那就开始吧. 屏蔽短信功能 还可沿用之前的6.0 处理方法, 在 SmsReceiverService ...

  8. Java实现发送短信验证验证码功能

    这几天老大让我弄一个发送短信验证码的功能,使用的是信易通的短信平台接口,然后在Java中使用HttpClient模拟POST请求或者GET请求(看短信平台要求,一般的情况下都是POST请求),调用短信 ...

  9. 【物联网智能网关-03】GPRS模块中文短信收发

    在去年年初,就已经推出V1.0.0的GPRS库,不过在这个版本上只是实现了西文短信收发和字符串方式的GPRS数据通信,功能还相对不完善(参见我以前的博文<GPRS通信实现>).最近升级的版 ...

最新文章

  1. Java日志框架-Logback手册中文版以及官方配置文档教程
  2. 多协议注入工具t50
  3. 使用OpenCV进行标定(Python)
  4. Java为什么我们现在有时不用环境变量就可以运行了
  5. LeetCode Algorithm LCP 44. 开幕式焰火
  6. 十四种Java开发工具点评
  7. linux挂载磁盘阵列
  8. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第18篇]画一个/描述ECB,CBC,CTR模式的操作
  9. sqlserver 性能计数器的问题
  10. linux 双网卡 debian,Linux服务器双网卡双IP和单网卡双IP配置方法(Debian/Ubuntu)
  11. 记第一次在程序中埋彩蛋
  12. HDF5快速上手全攻略
  13. Python爬虫爬取豆瓣图书的信息和封面,放入MySQL数据库中。
  14. 计算机网盘打不开,电脑百度网盘无法打开视频的解决方法|电脑百度网盘无法打开视频如何解决...
  15. Dilated Convolution(空洞卷积、膨胀卷积)详解
  16. Python下载和安装图文教程[超详细]
  17. 小米笔记本 镜像_小米笔记本Air 13.3 指纹版安装黑苹果 macOS High Sierra 10.13 教程...
  18. Unity在Hex与Color之间的颜色转换
  19. JavaScript 每日一题 #10
  20. 视觉伺服入门第二步:带你从经典论文阅读Visual Servo Control Part II: Advanced Approaches进阶版

热门文章

  1. 如何制作优质的短视频
  2. 【大数据】大数据学习
  3. 沿用供应商批号进行批号管理的优劣分析
  4. 微信小游戏学习日记2
  5. Python线性规划库Pulp的详解及应用示例
  6. 北京市顺义区谷歌卫星地图下载
  7. Excel办公技巧:Excel表格权限设置,这方法厉害
  8. 双月湾海边+农家乐模式市场调研报告
  9. 通信原理包络是什么意思_直缝钢管的矫直原理
  10. PDF转换成PPT免费软件介绍