最近项目中,需要用到smslib,在研究了两天之后,在这里写下一些心得,大家相互学习与交流。
一、前期工作
1. 准备工作:
a) 下载开源代码smslib.
b) 下载串口驱动包 javacomm20-win32
2. 环境配置:
在javacomm20-win32内找到comm.jar,win32com.dll,javac.com.propertites
%JAVA_HOME%\jre\lib\ext 下面放 comm.jar
%JAVA_HOME%\bin 下面放win32com.dll
%JAVA_HOME%\jre\lib 下面放 javax.comm.properties
3. 测试环境是否配置成功:
打开命令行工具,到路径为:E:\javacomm20-win32\commapi\samples\BlackBox
输入命令 java BlackBox:
a. 如果有界面产生,环境配置成功。
b. 如果显示找不到某一个类,可能是jdk环境变量的问题。
c. 如果显示找不到端口,那么步骤2出错。
二、服务类接口编写
包含方法:
Method1:int readMessage(MessageClasses classes,Llist<InBoundMessage> msgs);
Param1: 包含3种类别READ,UNREAD,ALL。
Param2: 读到消息所放容器。
Return : 返回数据条数。
Method2:Boolean sendMessage(String mobileNum,String content);
Param1: 要发送的电话号码。
Param2: 要发送的内容。
Return : true|false
Method3:Boolean deleteMessage(InBoundMessage msg);
Param1: 要删除的消息
Return: true|false
Mehtod4:void deleteMessages(List<InBoundMessage> msgs);
Params1: 要删除的消息
2. 包含变量:
Variable1:String smsInfos; sms信息
Format: simNum#gateId#comNum#baud#factory#SMS_centor;
Variable2:SmsMessageProcessor processor;
Method: public Boolean process(InboundMessage msg);
userFor:用于处理收到的消息,使用的人实现处理类。
3. 工作线程:
由于InboundNotification测试过程中,不能达到要求,只能写一个线程,一直读sms的内容。
While(true){
readMessage(ALL,msgs);
for(InboundMessage msg:msgs){
processor.process(msg);
deleteMessage(msg);
}
Thread.sleep(1000);
}
这里需要注明一下:本来想利用InboundNotification,每当有消息进来,就使用processor去处理,可是,后来测试发现,这个类,使用起来不是特别灵活,无法做到,已有消息就进入,这里如果有知道的朋友,可以指导一下我。
下面将代码贴上。
启动类。
package cn.hexing.sms;
import cn.hexing.sms.processor.DefaultSmsMsgProcessor;
public class Start {
public static void main(String[] args) throws Exception {
SmsService.getInstance().setSmsInfos("+8613989464741#modem.com3#COM3#115200#Simcom#+8613800571500");
SmsService.getInstance().setProcessor(new DefaultSmsMsgProcessor());
SmsService.getInstance().startService();
}
}
Sms服务类
package cn.hexing.sms;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.crypto.spec.SecretKeySpec;
import org.smslib.AGateway;
import org.smslib.AGateway.GatewayStatuses;
import org.smslib.AGateway.Protocols;
import org.smslib.GatewayException;
import org.smslib.ICallNotification;
import org.smslib.IGatewayStatusNotification;
import org.smslib.IInboundMessageNotification;
import org.smslib.IOrphanedMessageNotification;
import org.smslib.IOutboundMessageNotification;
import org.smslib.InboundMessage;
import org.smslib.InboundMessage.MessageClasses;
import org.smslib.Message.MessageEncodings;
import org.smslib.Message.MessageTypes;
import org.smslib.OutboundMessage;
import org.smslib.SMSLibException;
import org.smslib.Service;
import org.smslib.TimeoutException;
import org.smslib.crypto.AESKey;
import org.smslib.modem.SerialModemGateway;
import cn.hexing.sms.processor.DefaultSmsMsgProcessor;
import cn.hexing.sms.processor.SmsMsgProcessor;
public class SmsService {
private static SmsService instance;
private Service smsService;
/**消息处理器*/
private SmsMsgProcessor processor = new DefaultSmsMsgProcessor();
/**
* formate: simNum#gateId#comNum#baud#factory#SMS_centor;
**/
private String smsInfos;
private SmsService(){
}
public synchronized static SmsService getInstance(){
if (instance == null)
instance = new SmsService();
return instance;
}
public void stopService() throws Exception{
smsService.stopService();
}
public void startService() throws Exception{
smsService = Service.getInstance();
InboundNotification inboundNotification = new InboundNotification();
CallNotification callNotification = new CallNotification();
GatewayStatusNotification statusNotification = new GatewayStatusNotification();
OrphanedMessageNotification orphanedMessageNotification = new OrphanedMessageNotification();
smsService.setInboundMessageNotification(inboundNotification);
smsService.setCallNotification(callNotification);
smsService.setGatewayStatusNotification(statusNotification);
smsService.setOrphanedMessageNotification(orphanedMessageNotification);
OutboundNotification outboundNotification = new OutboundNotification();
smsService.S.SERIAL_POLLING = true;
smsService.setOutboundMessageNotification(outboundNotification);
String[] infos=smsInfos.split(";");
for(String info : infos){
String[] infomation = info.split("#");
SerialModemGateway gateway = new SerialModemGateway(infomation[1], infomation[2], Integer.parseInt(infomation[3]), infomation[4], "");
gateway.setProtocol(Protocols.PDU);
gateway.setInbound(true);
gateway.setOutbound(true);
gateway.setSimPin("0000");
gateway.setSmscNumber(infomation[5]); //短信中心号码+8613800571500
//当前sim卡号码
smsService.getKeyManager().registerKey(infomation[0], new AESKey(new SecretKeySpec("0011223344556677".getBytes(), "AES")));
smsService.addGateway(gateway);
}
smsService.startService();
//启动读线程
new WorkThread().start();
}
/**
* @param messageClasses 消息类,READ,UNREAD,ALL,读到的消息,直接删除了。
* @throws TimeoutException
* @throws GatewayException
* @throws IOException
* @throws InterruptedException
*/
public int readMessages(MessageClasses messageClasses,List<InboundMessage> msgList) throws Exception{
return smsService.readMessages(msgList,messageClasses);
}
/**
* 批量删除消息
* @param msgs
*/
public void deleteMessages(List<InboundMessage> msgs) {
for(InboundMessage msg:msgs){
deleteMessage(msg);
}
}
/**
* 删除一个消息
* @param msg
* @return
*/
public boolean deleteMessage(InboundMessage msg) {
try {
return this.smsService.deleteMessage(msg);
} catch (TimeoutException e) {
} catch (GatewayException e) {
} catch (IOException e) {
} catch (InterruptedException e) {
}
return false;
}
/**
* @param mobileNum 要发送的手机号码
* @param content 内容
* @return
* @throws TimeoutException
* @throws GatewayException
* @throws SMSLibException
* @throws IOException
* @throws InterruptedException
*/
public boolean sendMessage(String mobileNum,String content) throws Exception{
OutboundMessage message = new OutboundMessage(mobileNum,content);
message.setEncoding(MessageEncodings.ENCUCS2);
return smsService.sendMessage(message);
}
public class InboundNotification implements IInboundMessageNotification
{
public void process(AGateway gateway, MessageTypes msgType, InboundMessage msg)
{
// if (msgType == MessageTypes.INBOUND) System.out.println(">>> New Inbound message detected from Gateway: " + gateway.getGatewayId());
// else if (msgType == MessageTypes.STATUSREPORT) System.out.println(">>> New Inbound Status Report message detected from Gateway: " + gateway.getGatewayId());
}
}
public class CallNotification implements ICallNotification
{
public void process(AGateway gateway, String callerId)
{
// System.out.println(">>> New call detected from Gateway: " + gateway.getGatewayId() + " : " + callerId);
}
}
public class GatewayStatusNotification implements IGatewayStatusNotification
{
public void process(AGateway gateway, GatewayStatuses oldStatus, GatewayStatuses newStatus)
{
//System.out.println(">>> Gateway Status change for " + gateway.getGatewayId() + ", OLD: " + oldStatus + " -> NEW: " + newStatus);
}
}
public class OrphanedMessageNotification implements IOrphanedMessageNotification
{
public boolean process(AGateway gateway, InboundMessage msg)
{
//System.out.println(">>> Orphaned message part detected from " + gateway.getGatewayId());
//System.out.println(msg);
// Since we are just testing, return FALSE and keep the orphaned message part.
return false;
}
}
public class OutboundNotification implements IOutboundMessageNotification
{
public void process(AGateway gateway, OutboundMessage msg)
{
//System.out.println("Outbound handler called from Gateway: " + gateway.getGatewayId());
//System.out.println(msg);
}
}
class WorkThread extends Thread{
@Override
public void run() {
while(true){
try {
List<InboundMessage> msgs = new ArrayList<InboundMessage>();
readMessages(MessageClasses.ALL,msgs);
for(InboundMessage msg:msgs){
processor.process(msg);
deleteMessage(msg);
}
Thread.sleep(1000);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
public final SmsMsgProcessor getProcessor() {
return processor;
}
public final void setProcessor(SmsMsgProcessor processor) {
this.processor = processor;
}
public final String getSmsInfos() {
return smsInfos;
}
public final void setSmsInfos(String smsInfos) {
this.smsInfos = smsInfos;
}
}
processor接口
package cn.hexing.sms.processor;
import org.smslib.InboundMessage;
public interface SmsMsgProcessor {
public boolean process(InboundMessage msg);
}
默认实现的processor类
package cn.hexing.sms.processor;
import org.smslib.InboundMessage;
public class DefaultSmsMsgProcessor implements SmsMsgProcessor{
@Override
public boolean process(InboundMessage msg) {
System.out.println(msg.getText());
return false;
}
}