您的位置:首页 > 编程语言 > Java开发

SMSLib实现Java短信收发的功能

2013-03-29 16:32 369 查看


转载地址:http://sjsky.iteye.com/blog/1045502


SMSLib实现Java短信收发的功能

博客分类:

企业应用

JavaSMS企业应用SMSLib短信

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


package michael.comm.serial;



import java.util.Enumeration;



import javax.comm.CommDriver;

import javax.comm.CommPortIdentifier;

import javax.comm.SerialPort;



/**

* @author michael

*

*/

public class TestGetPortList {



/**

* @param args

* @throws Exception

*/

public static void main(String[] args) throws Exception {

// 人工加载驱动

// MainTest.driverInit();

TestGetPortList.getCommPortList();

// 人工加载驱动获取端口列表

// TestGetPortList.getPortByDriver();



}



/**

* 手工加载驱动<br>

* 正常情况下程序会自动加载驱动,故通常不需要人工加载<br>

* 每重复加载一次,会把端口重复注册,CommPortIdentifier.getPortIdentifiers()获取的端口就会重复

*/

public static void driverManualInit() {

String driverName = "com.sun.comm.Win32Driver";

String libname = "win32com";

CommDriver commDriver = null;

try {

System.loadLibrary("win32com");

System.out.println(libname + " Library Loaded");



commDriver = (javax.comm.CommDriver) Class.forName(driverName)

.newInstance();

commDriver.initialize();

System.out.println("comm Driver Initialized");



} catch (Exception e) {

System.err.println(e);

}

}



/**

* 获取端口列表

*/

public static void getCommPortList() {

CommPortIdentifier portId;

Enumeration portEnum = CommPortIdentifier.getPortIdentifiers();

while (portEnum.hasMoreElements()) {

portId = (CommPortIdentifier) portEnum.nextElement();



if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {

System.out.println("串口: name-" + portId.getName()

+ " 是否占用-" + portId.isCurrentlyOwned());

} else {

System.out.println("并口: name-" + portId.getName()

+ " 是否占用-" + portId.isCurrentlyOwned());

}

}

System.out.println("-------------------------------------");

}



/**

*

*/

public static void getPortByDriver() {



String driverName = "com.sun.comm.Win32Driver";

String libname = "win32com";

CommDriver commDriver = null;

try {

System.loadLibrary("win32com");

System.out.println(libname + " Library Loaded");



commDriver = (CommDriver) Class.forName(driverName).newInstance();

commDriver.initialize();

System.out.println("comm Driver Initialized");



} catch (Exception e) {

System.err.println(e);

}

SerialPort sPort = null;

try {



sPort = (SerialPort) commDriver.getCommPort("COM24",

CommPortIdentifier.PORT_SERIAL);

System.out.println("find CommPort:" + sPort.toString());

} catch (Exception e) {

System.out.println(e.getMessage());

}



}



}

本机运行结果:

引用

串口: 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代码


package michael.comm.serial;



import java.io.InputStream;

import java.io.OutputStream;

import java.util.Enumeration;



import javax.comm.CommPortIdentifier;

import javax.comm.SerialPort;



/**

* @author michael

*

*/

public class TestCommPort {

static CommPortIdentifier portId;

static Enumeration portList;

static int bauds[] = { 9600, 19200, 57600, 115200 };



/**

* @param args

*/

public static void main(String[] args) {

portList = CommPortIdentifier.getPortIdentifiers();

System.out.println("GSM Modem 串行端口连接测试开始...");

String portName = "COM24";

while (portList.hasMoreElements()) {

portId = (CommPortIdentifier) portList.nextElement();

if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL

&& portName.equals(portId.getName())) {

System.out.println("找到串口: " + portId.getName());

for (int i = 0; i < bauds.length; i++) {

System.out.print(" Trying at " + bauds[i] + "...");

try {

SerialPort serialPort;

InputStream inStream;

OutputStream outStream;

int c;

StringBuffer response = new StringBuffer();

serialPort = (SerialPort) portId.open(

"SMSLibCommTester", 2000);

serialPort

.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN);

serialPort.setSerialPortParams(bauds[i],

SerialPort.DATABITS_8, SerialPort.STOPBITS_1,

SerialPort.PARITY_NONE);

inStream = serialPort.getInputStream();

outStream = serialPort.getOutputStream();

serialPort.enableReceiveTimeout(1000);

c = inStream.read();

while (c != -1) {

c = inStream.read();

}

outStream.write('A');

outStream.write('T');

outStream.write('\r');

try {

Thread.sleep(1000);

} catch (Exception e) {

}

c = inStream.read();

while (c != -1) {

response.append((char) c);

c = inStream.read();

}

if (response.indexOf("OK") >= 0) {

System.out.print(" 正在检测设备:");

try {

outStream.write('A');

outStream.write('T');

outStream.write('+');

outStream.write('C');

outStream.write('G');

outStream.write('M');

outStream.write('M');

outStream.write('\r');

response = new StringBuffer();

c = inStream.read();

while (c != -1) {

response.append((char) c);

c = inStream.read();

}

System.out.println(" 发现设备: "

+ response.toString().replaceAll(

"(\\s+OK\\s+)|[\n\r]", ""));

} catch (Exception e) {

System.out.println(" 检测设备失败,获取设备信息异常:"

+ e.getMessage());

}

} else {

System.out.println(" 检测设备失败,沒有接收到响应结果!");

}

serialPort.close();

} catch (Exception e) {

System.out.println(" 检测设备失败,发生异常:" + e.getMessage());

}

}

}

}

}

}

运行结果如下:

引用

GSM Modem 串行端口连接测试开始...

找到串口: COM24

Trying at 9600... 正在检测设备: 发现设备: AT+CGMM MULTIBAND 900E 1800

Trying at 19200... 发现设备失败,沒有接收到响应结果!

Trying at 57600... 发现设备失败,沒有接收到响应结果!

Trying at 115200... 发现设备失败,沒有接收到响应结果!

【四】、测试收发短信:

Java代码


package michael.sms;



import java.util.ArrayList;

import java.util.LinkedList;

import java.util.List;



import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.smslib.AGateway;

import org.smslib.GatewayException;

import org.smslib.InboundMessage;

import org.smslib.OutboundMessage;

import org.smslib.Service;

import org.smslib.AGateway.Protocols;

import org.smslib.Message.MessageEncodings;

import org.smslib.modem.SerialModemGateway;



/**

* @author michael

*

*/

public class SmsHandler {

private static final Logger logger = Logger.getLogger(SmsHandler.class);



private Service smsService;



/**

*

*/

public SmsHandler() {

smsService = Service.getInstance();

List<AGateway> agatewayList = new ArrayList<AGateway>();



String portName = "COM24";//"/dev/ttyUSB0";// COM24

SerialModemGateway gateway = new SerialModemGateway(

"modem." + portName, portName, 9600, "wavecom", "PL2303");

gateway.setInbound(true);

gateway.setOutbound(true);

gateway.setProtocol(Protocols.PDU);

gateway.setSimPin("0000");

agatewayList.add(gateway);

try {

for (AGateway gatewayTmp : agatewayList) {

smsService.addGateway(gatewayTmp);

}

} catch (GatewayException ex) {

logger.error(ex.getMessage());

}

}



/**

*

*/

public void start() {

logger.info("SMS service start.....");

try {

smsService.startService();

} catch (Exception ex) {

logger.error("SMS service start error:", ex);

}

}



/**

*

*/

public void destroy() {

try {

smsService.stopService();

} catch (Exception ex) {

logger.error("SMS service stop error:", ex);

}

logger.info("SMS service stop");

}



/**

* send SMS

* @param msg

* @return Boolean

*/

public Boolean sendSMS(OutboundMessage msg) {

try {

msg.setEncoding(MessageEncodings.ENCUCS2);

return smsService.sendMessage(msg);

} catch (Exception e) {

logger.error("send error:", e);

}

return false;

}



private boolean isStarted() {

if (smsService.getServiceStatus() == Service.ServiceStatus.STARTED) {

for (AGateway gateway : smsService.getGateways()) {

if (gateway.getStatus() == AGateway.GatewayStatuses.STARTED) {

return true;

}

}

}

return false;

}



/**

* read SMS

* @return List

*/

public List<InboundMessage> readSMS() {

List<InboundMessage> msgList = new LinkedList<InboundMessage>();

if (!isStarted()) {

return msgList;

}

try {

this.smsService.readMessages(msgList,

InboundMessage.MessageClasses.ALL);

logger.info("read SMS size: " + msgList.size());

} catch (Exception e) {

logger.error("read error:", e);

}

return msgList;

}



/**

* @param args

*/

public static void main(String[] args) {

Logger.getRootLogger().setLevel(Level.INFO);

OutboundMessage outMsg = new OutboundMessage("189xxxx****", "信息测试");

SmsHandler smsHandler = new SmsHandler();

smsHandler.start();

//发送短信

smsHandler.sendSMS(outMsg);

//读取短信

List<InboundMessage> readList = smsHandler.readSMS();

for (InboundMessage in : readList) {

System.out.println("发信人:" + in.getOriginator() + " 短信内容:"

+ in.getText());

}

smsHandler.destroy();

System.out.println("-----------");

}



}

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

引用

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

-----------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: