如何使用Java通信API和GSM调制解调器接听电话

11
我已经成功实现了Java API,并开始发送短信和拨打电话。但是,我发现无法接听来电。我尝试使用 RI 事件(serialPort.notifyOnRingIndicator(true);),但它没有触发,只有DATA_AVAILABLE事件在触发。
  1. 我尝试读取输入缓冲区并在检测到“RING”时发送ATA命令,但它不起作用,即使从InputStream直接写入控制台时也包含RING。
  2. 尝试在串行事件处理程序中的FROM Case RI(Ring Indicator)发送ATA命令。

我正在尝试实现IVR系统。在这种情况下如何发送ATA命令,如何检测RING以及为什么RI事件没有触发。

代码

package sample;



    import java.io.*;
    import java.util.*;

    import gnu.io.*;

    import java.io.*;

    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;

    import org.apache.log4j.chainsaw.Main;

    import sun.audio.*;

    public class GSMConnect implements SerialPortEventListener, 
     CommPortOwnershipListener {

     private static String comPort = "COM6"; // This COM Port must be connect with GSM Modem or your mobile phone
     private String messageString = "";
     private CommPortIdentifier portId = null;
     private Enumeration portList;
     private InputStream inputStream = null;
     private OutputStream outputStream = null;
     private SerialPort serialPort;
     String readBufferTrial = "";
     /** Creates a new instance of GSMConnect */
     public GSMConnect(String comm) {

       this.comPort = comm;

     }

     public boolean init() {
       portList = CommPortIdentifier.getPortIdentifiers();
       while (portList.hasMoreElements()) {
         portId = (CommPortIdentifier) portList.nextElement();
         if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
           if (portId.getName().equals(comPort)) {
               System.out.println("Got PortName");
             return true;
           }
         }
       }
       return false;
     }

     public void checkStatus() {
       send("AT+CREG?\r\n");
     }

     public void dial(String phoneNumber) {
       try {
    //dial to this phone number

         messageString = "ATD" + phoneNumber + ";\r\n";
         outputStream.write(messageString.getBytes());
         System.out.println("Called ");
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     public void send(String cmd) {
       try {
         outputStream.write(cmd.getBytes());
       } catch (IOException e) {
         e.printStackTrace();
       }
     }

     public void sendMessage(String phoneNumber, String message) {
           char quotes ='"';
       send("AT+CMGS="+quotes + phoneNumber +quotes+ "\r\n");
       try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
        //   send("AT+CMGS=\""+ phoneNumber +"\"\r\n");
       send(message + '\032');
       System.out.println("Message Sent");
     }

     public void hangup() {
       send("ATH\r\n");
     }
     public void welcomeMessage(){

         // open the sound file as a Java input stream
            String gongFile = "C:\\Users\\SACHIN\\Desktop\\7001110.mp3";
            InputStream in;
            try {
                in = new FileInputStream(gongFile);
                 // create an audiostream from the inputstream
               // AudioStream audioStream = new AudioStream(in);
                // play the audio clip with the audioplayer class
               // AudioPlayer.player.start(audioStream);
                Clip clip = AudioSystem.getClip();
                AudioInputStream inputStream = AudioSystem.getAudioInputStream(
                  Main.class.getResourceAsStream(gongFile));
                clip.open(inputStream);
                clip.start(); 
            } catch (IOException | UnsupportedAudioFileException | LineUnavailableException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }





     }
     public void connect() throws NullPointerException {
       if (portId != null) {
         try {
           portId.addPortOwnershipListener(this);

           serialPort = (SerialPort) portId.open("MobileGateWay", 2000);
           serialPort.setSerialPortParams(115200,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);
         } catch (PortInUseException | UnsupportedCommOperationException e) {
           e.printStackTrace();
         }

         try {
           inputStream = serialPort.getInputStream();
           outputStream = serialPort.getOutputStream();

         } catch (IOException e) {
           e.printStackTrace();
         }

         try {
           /** These are the events we want to know about*/
           serialPort.addEventListener(this);
           serialPort.notifyOnDataAvailable(true);
           serialPort.notifyOnRingIndicator(true);
         } catch (TooManyListenersException e) {
           e.printStackTrace();
         }

    //Register to home network of sim card

         send("ATZ\r\n");

       } else {
         throw new NullPointerException("COM Port not found!!");
       }
     }

     public void serialEvent(SerialPortEvent serialPortEvent) {
       switch (serialPortEvent.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:
             System.out.println("Ringing");

        /*try {
            Thread.sleep(5000);
            send("ATA");
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }*/
        break;
         case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
         case SerialPortEvent.DATA_AVAILABLE:

           byte[] readBuffer = new byte[2048];
           try {
             while (inputStream.available() > 0) 
             {
               int numBytes = inputStream.read(readBuffer);

               System.out.print(numBytes);
               if((readBuffer.toString()).contains("RING")){
               System.out.println("Enter Inside if RING Loop");    


               welcomeMessage();
               }
             }
             //readBufferTrial=readBufferTria;//+new String(readBuffer)+new Date();
             //print response message
             System.out.print(new String(readBuffer));
           } catch (IOException e) {
           }
           break;
       }
     }
     public void outCommand(){
         System.out.print(readBufferTrial);
     }
     public void ownershipChange(int type) {
       switch (type) {
         case CommPortOwnershipListener.PORT_UNOWNED:
           System.out.println(portId.getName() + ": PORT_UNOWNED");
           break;
         case CommPortOwnershipListener.PORT_OWNED:
           System.out.println(portId.getName() + ": PORT_OWNED");
           break;
         case CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED:
           System.out.println(portId.getName() + ": PORT_INUSED");
           break;
       }

     }
     public void closePort(){

        serialPort.close(); 
     }

     public static void main(String args[]) {
       GSMConnect gsm = new GSMConnect(comPort);
       if (gsm.init()) {
         try {
             System.out.println("Initialization Success");
           gsm.connect();
           Thread.sleep(5000);
           gsm.checkStatus();
           Thread.sleep(5000);
           System.out.println("Before Auto Answer");
           gsm.send("ATS0=1");
           Thread.sleep(7500);
           System.out.println("After Auto Answer set");

        //   gsm.sendMessage("87SSSXXX9105", "Trial Success ");
           Thread.sleep(5000);
         //   gsm.sendMessage("+919633XXXXX", "Third Msg");
         //  Thread.sleep(1000);
         //  gsm.dial("87SSSXXX9105");
         //  gsm.dial("87SSSXXX9105");
         //  Thread.sleep(1000);
         //  gsm.welcomeMessage();
        //   Thread.sleep(1000);
         //  gsm.welcomeMessage();// for turning on Echo ATE1&W

           Thread.sleep(20000);

           gsm.hangup();
           Thread.sleep(1000);
           gsm.closePort();
           gsm.outCommand();
           System.exit(1);


         } catch (Exception e) {
           e.printStackTrace();
         }
       } else {
         System.out.println("Can't init this card");
       }
     }


    }

编辑:

我找到了一种通过在调制解调器初始化后使用AT命令设置自动应答模式来自动应答电话的方法,但它并不总是可靠的。而且,为了达到我使用调制解调器的目的,我需要在电话被接听时准确地播放音频剪辑。使用AT命令进行自动应答可以自动接听电话,但播放音频的问题仍然存在。因此,我需要找到一种检测铃声的方法。


1
看起来这可能会对你有所帮助 https://www.daniweb.com/software-development/java/threads/14224/connecting-modem-via-java - mussdroid
@mussdroid,是的,这和我尝试的是一样的,但问题在于我的 RI 代码没有触发,即使我的 inputstream 包含 RING RING,在控制台中打印出来,但如果将同一字符串与“RING”进行比较,则无法找到它,因此导致了等效于 RI Case 不触发的情况,感谢您的帮助。 这是我设置赏金之后得到的第一个回复。 - codefreaK
这里需要解释的主要问题是RI事件未触发,因为在深入了解应用程序的细节之前,我需要理解这一点。 - codefreaK
2个回答

1
我无法与具体的API进行交流或解释为什么您没有收到事件。但是,您的备用计划是解析inputStream以查找RING,这有一些潜在的问题。
其中一个主要问题是,您的实现取决于在同一读取操作中发送/读取RING。这并不保证-根据底层API的实现方式,很可能会一次一个字节地获取流(在这种情况下,您将获得R I N G作为单独的字符串)。
我的建议是创建一个StringBuffer,在输入时将其附加到StringBuffer,然后检查StringBuffer。
类似于以下内容:
 case SerialPortEvent.DATA_AVAILABLE:

   StringBuffer sb = new StringBuffer();
   byte[] readBuffer = new byte[2048];
   try {
     while (inputStream.available() > 0) 
     {
       int numBytes = inputStream.read(readBuffer);
       sb.append(new String(readBuffer,0,numBytes));
       System.out.print(numBytes);
     }
     if((sb.toString()).contains("RING")){
        System.out.println("Enter Inside if RING Loop");    
        welcomeMessage();
     }
     //print response message
     System.out.print(sb.toString());
   } catch (IOException e) {
   }
   break;

0
请查看您的 switch case,您没有加上 break; 这可能是问题所在。
case SerialPortEvent.RI:
            if( serialPortEvent.getNewValue() ) 
            {
                System.out.println("Ring Indicator On");
            }
            else 
            {
                System.out.println("Ring Indicator Off");
            }
            break;

好的,我会看一下并回复你。但问题是我尝试了只有RI情况并注释掉DataAvailable事件或将其设置为空,但仍然没有触发。所以很可能不起作用。事件只设置为serialPort.notifyOnDataAvailable(false)。 - codefreaK
我贴在这里的代码没有break,它消失了,因为其中还有其他代码,在格式化以放入这个页面时,我不小心将其删除了。 - codefreaK
在你当前的代码中,你只在 case SerialPortEvent.DATA_AVAILABLE: 处使用了 break,那么在 serialPortEven.RI case 后面是否也有 break?你仍需要加入 if else 来判断它是开还是关。 - mussdroid
是的,没错,它从入口点执行,你可能需要检查程序是否进入了 switch case 语句。 - mussdroid
这就是我整个问题的关键,即使输入流包含 RING RING,也没有进入 RI 事件处理程序,即来电响铃时 RI 事件没有触发。 - codefreaK
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接