SerialBuffer类的实现
对于SerialBuffer类有一点需要说明一下,就是在putChar和getMsg方法前必须加synchoronized关键字,这是因为这个类是在多线程中调用,由于在这两个方法中访问了共享资源,为了不出现脏数据,因此,必须加这个关键字。package com.message;
![]()
public class SerialBuffer ...{
private String content = "";
private String currentMsg, tempContent;
private boolean available = false;
private int lengthNeeded = 1;
![]()
// 这个函数返回指定长度的信息串
public synchronized String getMsg(int length)
...{
lengthNeeded = length;
notifyAll();
![]()
if (lengthNeeded > content.length()) ...{
available = false;
while (available == false) ...{ // 循环等待,直到可以读数据为止
try ...{
wait();
}
catch (InterruptedException e) ...{}
}
}
![]()
currentMsg = content.substring(0, LengthNeeded);
tempContent = content.substring(LengthNeeded);
content = tempContent;
lengthNeeded = 1;
notifyAll();
return currentMsg;
}
![]()
// 这个方法将一个字符写入COM口
public synchronized void putChar(int c) ...{
Character d = new Character( (char) c);
content = Content.concat(d.toString());
if (lengthNeeded < Content.length()) ...{
available = true;
}
notifyAll();
}
}
readSerial类的实现
接下来实现负责通过数据线和手机通信的类OperateMobile。这个类可以通过send方法控制手机发送短信。package com.message;
![]()
import Java.io.*;
![]()
// 这个类从指定的COM口读数据,并将这些数据保存在缓冲区中
// ReadSerial是一个线程类
public class ReadSerial extends Thread ...{
private SerialBuffer comBuffer;
private InputStream comPort;
![]()
// 这个方法是ReadSerial类的构造函数,第一个参数将缓冲区传入类中,第二个参数// 是被打开的COM口的输入流
public ReadSerial(SerialBuffer serialBuffer, InputStream port) ...{
comBuffer = serialBuffer;
comPort = port;
}
// 调用Thread的start方法后,运行run方法
public void run() ...{
int c;
try ...{
while (true) ...{
c = comPort.read(); // 一个字符、一个字符地从COM口读数据
comBuffer.putChar(c);
}
}
catch (IOException e) ...{}
}
}
最后让我们调用OperateMobile类来发送短信。public class OperateMobile
...{
private MySerial mySerial;
private static char symbol = 10;
private static char symbol1 = 13;
![]()
public static boolean open(int port) ...{
mySerial = new MySerial(port);
if (mySerial.Initialize() == 1) ...{
return true;
}
else ...{
return false;
}
}
// 设置短信发送模式
private static boolean setMode(int mode)
String strReturn, strSend = “”;
try ...{
// 模式字符串
strSend = "AT+CMGF=" + String.valueOf(mode) +
String.valueOf(symbol1);
// 将模式通过COM口写入手机
mySerial.WritePort(strSend);
strReturn = "";
// 从手机读出长度为6的返回信息,如果包含“OK”,则说明设置成功
strReturn = mySerial.ReadPort(6);
if (strReturn.indexOf("OK", 0) != -1) ...{
return true;
}
return false;
}
catch (Exception ex) ...{
return false;
}
}
public static boolean send (String phoneCode, String msg) ...{
String strReturn = “”, strSend = “”;
char symbol2 = 34;
char symbol3 = 26;
if (setMode(1) != true) ...{ // 设置短信发送模式
return false;
}
try ...{
strSend = "AT+CSMP=1,173,36,08" + String.valueOf(symbol1);
mySerial.writePort(strSend);
sleep(300);
strReturn = mySerial.ReadPort(6); // 读返回字符串
if (strReturn.indexOf("OK", 0) != -1) ...{ // 如果成功,进行下一步
// 将对方的电话号传入手机
strSend = "AT+CMGS=" + String.valueOf(symbol2) + phoneCode +
String.valueOf(symbol2) +
String.valueOf(symbol1);
mySerial.writePort(strSend);
strReturn = "";
sleep(200);
strReturn = mySerial.ReadPort(4);
byte[] str1 = null;
try ...{
str1 = msg.getBytes("GBK");
}
catch (Java.io.UnsupportedEncodingException e) ...{
e.printStackTrace();
}
// 将发送信息变成十六进制发送
strSend = encodeHex(str1, msg) + String.valueOf(symbol3) +
String.valueOf(symbol1);
mySerial.writePort(strSend);
sleep(200);
strReturn = mySerial.ReadPort(8); // 读信息以确定是否发送成功
if (strReturn.indexOf("+CMGS", 0) != -1) ...{
System.out.println("OK");
return true;
}
}
return false;
}
catch (Exception ex) ...{
ex.printStackTrace();
return false;
}
}
// 这个方法对要发送的信息进行编码
private static final String encodeHex(byte[] bytes, String msg) ...{
StringBuffer buff = new StringBuffer(bytes.length * 4);
String b;
char a;
int n = 0;
int m = 0;
for (int i = 0; i < bytes.length; i++) ...{
b = Integer.toHexString(bytes[i]);
if (bytes[i] > 0) ...{
buff.append("00");
buff.append(b);
n = n + 1;
}
else ...{
a = msg.charAt( (i - n) / 2 + n);
m = a;
b = Integer.toHexString(m);
buff.append(b.substring(0, 4));
![]()
i = i + 1;
}
}
return buff.toString();
}
![]()
}
五、 小结public class Main
...{
public static void main(String[] args) ...{
OperateModile.open(1); // 打开COM1端口(要将数据线插到COM1上)
OperateModile.send(“13912345678”, “收到我的短信了吗?收到了请回复?”);
}
}
使用计算机控制手机发送短信具有很大的灵活性。以上的例子只是抛砖引玉,读者可以通过这个例子进行扩展,设计出更灵活、更强大的发送短信的软件。这样,就不用再一个字一个字地在手机上输汉字了!
