最近在用Java写一个发短信的程序,是用jacob调用alasunsmscon.ocx控件连接短信猫设备,发送短信。现在能够实现发短信的功能,也能提示收到短信,但是无法读取短信内容。
alasunsmscon.ocx里面有一ReadMsg方法,控件使用手册中描述如下:读取设备新收到的短消息 (ReadMsg)
功能描述:读取设备新收到的短消息
参数: sNo string 收到短信的来源号码
sCon string 收到短信的内容
sMsgCenterNo string 短信中心号码
dSendTime date 发送短信的时间
iSendTimeZone Integer 发送短信的时区
返回: Long 0 读取成功, 其他 读取失败当设备收到短信时,会自动触发 OnReceive这个事件,请在此事件中调用ReadMsg方法
-----------------------------------------------------------------
上面这段是控件使用手册中的说明
我感觉按上面的意思是,把sNo,sCon,sMsgCenterNo,dSendTime,iSendTimeZone这几个参数传给ReadMsg,
调用ReadMsg之后,它会把收到的短信的所有信息返回给sNo,sCon,sMsgCenterNo,dSendTime,iSendTimeZone这几个参数。我写的OnReceive响应函数如下,
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
......
private final ActiveXComponent comx=new ActiveXComponent("alasun.alasunsms");
private final Dispatch ob = comx.getObject();
......
public void OnReceive(Variant args[]){
System.out.println("收到短信!");
  String sNo=null, sCon=null, sMsgCenterNo=null;//收到短信的来源号码//收到短信的内容//短信中心号码
Date dSendTime=null;//发送短信的时间
int iSendTimeZone;//时区        Variant ReadMsg = Dispatch.call(ob,"ReadMsg",sNo,sCon,sMsgCenterNo,dSendTime,iSendTimeZone);        if(0 == ReadMsg.getInt())
        {
        System.out.println(dSendTime + "收到来自" + sNo + "的短信,短信中心号:"+sMsgCenterNo + "短信内容:" + sCon);
    }
}运行以后,收到短信时,会输出如下信息:
收到短信!
null收到来自null的短信,短信中心号:null短信内容;null也就是说能够响应设备产生的OnReceive事件,同时ReadMsg方法也调用成功,但是传进去参数的值并没有被改变,返回的信息全都是空。我调用其它只有函数本身返回值的函数时,使用Dispatch.call()是可以成功调用的。我的问题是:在用jacob的dispatch调用控件里像ReadMsg()这样通过传进参数返回很多信息的函数时,应该怎样调用?
或者是不用Dispatch.call(),而用其它的方法实现?

解决方案 »

  1.   

    你这里打印出来的null值是它本身就是一些null而已,而不是说你执行到了具体的内容方法,就相当于你执行一个过程程序,这个程序本身没有问题,所以它会良好的运行,但是功能不一定实现了,因为,它所需要的这些内容并没有实现出来。所以,需要检查功能项吧,你上面的说调用成功与否我不敢说,不过值得你去试一下,希望早日解决,呵呵,
      

  2.   

    方法调用确实是成功的,因为发送的功能就是利用了SendMsg()的返回值等于0, 发出去的短信别人能够收到。
    这个控件有一个VB写的示例的程序,它里面的OnReceive()方法是这样写的:
    Private Sub alasunsms1_OnReceive()
        Dim sNo As String, sCon As String, sMsgCenterNo As String
        Dim dSendTime As Date, lTimeZone As Integer
        If alasunsms1.ReadMsg(sNo, sCon, sMsgCenterNo, dSendTime, lTimeZone) = 0 Then
            txtReceive.Text = dSendTime & "收到来自" & sNo & "的短信,短信中心号:" & sMsgCenterNo & "内容:" & sCon
        End If
    End Sub它是直接调用ReadMsg(sNo, sCon, sMsgCenterNo, dSendTime, lTimeZone)方法后,传进去的参数就可以被赋值,这个VB程序试过,是可以接收到短信内容的。只是在Java里,我不知道如何用Jacob调用这种方法,就是需要ReadMsg把它读到信息 通过我传进去的几个参数给返回回来,就是调用后那几个参数的值是被改变了的。还请高手指教...
      

  3.   

    package comm;import java.io.*;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.TooManyListenersException;
    import javax.comm.*;
    public class SerialComm implements SerialPortEventListener, Runnable {
    public final static String PORT_OWER = "MonitorApp"; private boolean isOpen; private boolean isStart; private boolean isSave; private boolean isPrint; private Thread readThread; private String portName; private String portAddress; private CommPortIdentifier portId; private SerialPort serialPort; private DataInputStream inputStream; private OutputStream outputStream; private SimpleDateFormat formatter; // prase data with process
    private String dataProtocol; private Object readWriteLock = new Object(); public SerialComm() {
    isOpen = false;
    isStart = false;
    isSave = true;
    isPrint = false;
    formatter = new SimpleDateFormat("[yyyy-MM-dd hh:mm:ss,SSS]"); portName = "COM1";
    portAddress = "LOCAL";
    dataProtocol = "Gooseli";
    } public void init(String port, String protocol) throws Exception {
    portName = port;
    portAddress = portName;
    dataProtocol = protocol; init();
    } public void init(String port, String address, String protocol)
    throws Exception {
    portName = port;
    portAddress = address;
    dataProtocol = protocol; init();
    } public void init() throws IOException, Exception, Exception {
    if (isOpen) {
    close();
    } try {
    // 传送串口名创建CommPortIdentifier对象服务。
    portId = CommPortIdentifier.getPortIdentifier(portName); // 使用portId对象服务打开串口,并获得串口对象
    serialPort = (SerialPort) portId.open(PORT_OWER, 2000); // 通过串口对象获得读串口流对象
    inputStream = new DataInputStream(serialPort.getInputStream()); // 通过串口对象获得写串口流对象
    outputStream = serialPort.getOutputStream(); isOpen = true;
    } catch (NoSuchPortException ex) {
    throw new Exception(ex.toString());
    } catch (PortInUseException ex) {
    throw new Exception(ex.toString());
    }
    } public void start() throws Exception {
    if (!isOpen) {
    throw new Exception(portName + " has not been opened.");
    } try {
    // 创建对象线程
    readThread = new Thread(this);
    readThread.start(); // 设置串口数据时间有效
    serialPort.notifyOnDataAvailable(true); // 增加监听
    serialPort.addEventListener(this); isStart = true; } catch (TooManyListenersException ex) {
    throw new Exception(ex.toString());
    }
    } public void run() {
    String at = "at^hcmgr=1\r"; String strTemp = at + (char) Integer.parseInt("1a", 16) + "z"; writeComm(strTemp);
    isPrint = true;
    } public void stop() {
    if (isStart) {
    serialPort.notifyOnDataAvailable(false);
    serialPort.removeEventListener(); isStart = false;
    }
    } public void close() {
    stop(); if (isOpen) {
    try {
    inputStream.close();
    outputStream.close();
    serialPort.close(); isOpen = false;
    } catch (IOException ex) {
    }
    }
    } // 如果串口有数据上报则主动调用此方法
    public void serialEvent(SerialPortEvent event) {
    switch (event.getEventType()) {
    case SerialPortEvent.BI:
    case SerialPortEvent.OE:
    case SerialPortEvent.FE:
    case SerialPortEvent.PE:
    case SerialPortEvent.CD:
    case SerialPortEvent.CTS:
    case SerialPortEvent.DSR:
    case SerialPortEvent.RI:
    case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
    break;
    case SerialPortEvent.DATA_AVAILABLE:
    readComm();
    break;
    default:
    break;
    }
    } public void readComm() {
    StringBuffer readBuffer = new StringBuffer();
    String scannedInput = "";
    Date currentTime = null;
    String TimeStamp = "";
    int c;
    char a;
    try {
    InputStreamReader fis = new InputStreamReader(inputStream, "utf-8");
    while ((c = fis.read()) != -1) {
    readBuffer.append((char) c);
    }
    scannedInput = readBuffer.toString().trim();
    currentTime = new Date(); TimeStamp = formatter.format(currentTime); } catch (IOException ex) {
    ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace();
    } } public void writeComm(String outString) {
    synchronized (readWriteLock) {
    try {
    outputStream.write(outString.getBytes());
    } catch (IOException ex) { }
    }
    } public static void main(String[] args) {
    SerialComm serialcomm = new SerialComm(); try {
    serialcomm.init("COM1", "Air");// windows下测试端口 // serialcomm.init("/dev/ttyUSB0", "Air");//linux下测试端口
    serialcomm.start();
    } catch (Exception ex) {
    }
    }}
    这个是串口通信的,应当差不多.
      

  4.   

    Java中的String类相当于是char[]的包装类。包装类的特质之一就是在对其值进行操作时会体现出其对应的基本类型的性质,即参数传递时是值传递,无法改变传入参数的内容。
      

  5.   

    我最近也在搞调用ocx中的方法,关注。