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

sms 的java二次开发

2009-02-25 13:40 274 查看
很多sms modem的二次开发中间件都是收费的,但最近项目需要控制终端设备用sms通信,作为一个开源阵营追随者实在不想让老板花这钱,所以就自己动手写了一个程序用来读写SMS modem,不过还真给实现了,过程中也借鉴了网友的一些成果,特别感谢他们。我只是实现了读写短信功能,当然如果还需要其他功能也是不难的,只要向SMS发送AT指令就可以了,相信都能够实现。一般的SMS modem使用COM 口通信的,也有使用USB的。发送AT指令是通过StringWriter完成,当SMS得到AT后据会做相应动作,并把完成结果包含有"OK","ERROR"的串返回到COM口,在用StreamReader取得作分析就行。

在实现过程中遇到的第一个困难就是中英文问题,需要转换编码方式才可发送成功。第二个就是短信长度问题,一般短信中文70,英文140,如果编码方式设置不好,即使是英文SMS也认为是中文而只能发送70长度,这就需要对“AT+CSMP=x,x,x,x”调试,因为对AT不熟悉,我可是TEST了好多次才成功,结果应为使用AT+CSMP=1,173,36,07,中文使用AT+CSMP=1,173,36,08,这方面希望熟悉AT的网友能共享您的知识。

java的端口通信就要使用的javax.comm.*包中的类,

javax.comm.SerialPort,javax.comm.CommPortIdentifier,当然还有些监听端口类我这里没有用到。使用这些类之前先做个简单的配置,如下:

1.把win32com.dll放到jre/bin 目录 如C:/Program Files/Java/jre6/bin
2.将Javax.comm.properties放到jre/lib目录 如:C:/Program Files/Java/jre6/lib

上面的文件因为这里无法上传附件,所以上传到我的资源中,连同源码都打包成java2sms.rar,可以下载。

=================

这样就可以尝试连接端口了

=================

CommPortIdentifier portId;
SerialPort serialPort;
OutputStreamWriter out;
InputStreamReader in;
public boolean open(String portName){

try {
portId = CommPortIdentifier.getPortIdentifier(portName);

try {
// 打开COM口, open方法的第二个参数是超时时间,单位是毫秒。
// 在本程序中超时时间是5秒
serialPort = (SerialPort) portId.open("Serial_Communication", 5000);
} catch (PortInUseException e) {
System.out.println("PortInUseException");
return false;
}

// 下面是得到用于和COM口通讯的输入、输出流。
try {
in = new InputStreamReader(serialPort.getInputStream());
out =new OutputStreamWriter(serialPort.getOutputStream());
} catch (IOException e) {
System.out.println("IOException");
return false;
}

// 下面是初始化COM口的传输参数,如传输速率:9600等。
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
System.out.println("UnsupportedCommOperationException");
return false;
}

} catch (NoSuchPortException e) {
System.out.println("NoSuchPortException");
return false;
}
return true;
}

=========

向COM 写入

=========

public void writeln(String s) throws Exception {
out.write(s);
out.write('/r');
out.flush();
}

============

从COM 读出

============

public String read() throws Exception {
int n, i;
char c;
String answer = new String("");
for (i = 0; i < 10; i++) {
while (in.ready()) {
n = in.read();
if (n != -1) {
c = (char)n;
answer = answer + c;
Thread.sleep(1);

phone [Timing]
} // if
else break;
} // while
Thread.sleep(100);
} // for
// System.out.println("read port: " + answer + "/n");
return answer;
}

===========

发送AT指令

===========

public synchronized String sendAT(String atcommand) throws java.rmi.RemoteException {
String s="";

try {
Thread.sleep(300);
writeln(atcommand);
for(int i=0;i<20;i++){
Thread.sleep(300);
s = read();

//为了等待结果回复
if(s.indexOf("OK", 0)>0 || s.indexOf("ERROR", 0)>0)
break;
}
} // try
catch (Exception e) {
System.out.println("ERROR: send AT command failed; " + "Command: " + atcommand + "; Answer: " + s + " " + e);
} // catch
return s;
} // sendAT

自定义类:

port :如上面代码讲解,用来COM通信,很简单不再啰嗦。

Message:盛放SMS对象,包含了SMS的一些属性。

VirtualObj: sms modem对象,实现发送,接收短信功能,如果需要其他如彩信,电话本...其他功能只要扩充它就可以。这里要说明的是 1.我的短信都是已Text方式发送的,即AT+CMGF=1,没有测试AT+CMGF=0的UDF方式,这个没有测试过,因为时间紧迫。2.中英文方面在发送时就做了判断。

if(msg.getBytes().length==msg.length()){
//english
if(msg.length()>140)
return false;
atCommand = "AT+CSMP=1,173,36,07";
}else{
//chinese
if(msg.length()>70)
return false;
atCommand = "AT+CSMP=1,173,36,08";
msg = StringUtil.encodeHex(msg);
}

至于编码方式为什么要用07,08这两个数字,我也不知道,测试出来的,希望网友能解决我这个困惑。

好了就这些吧,多说也没什么用,自己看代码最直接了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐