【问题标题】:How to Answer Call using Java Communication Api with GSM Modem Java如何使用带有 GSM 调制解调器 Java 的 Java Communication Api 接听电话
【发布时间】:2015-07-11 19:33:44
【问题描述】:

我已成功实现 Java Api 并开始发送短信和拨打电话。但我发现无法接听来电。我尝试了 RI 事件 (serialPort.notifyOnRingIndicator(true);)。但是它不仅触发了 DATA_AVAILABLE 事件正在触发

  1. 我已尝试读取输入缓冲区并在检测到“RING”时发送 ATA 命令但它无法检测到 RING,即使从 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命令接听电话,但播放音频的问题仍然存在。所以我需要一些方法来找到如何检测铃声

【问题讨论】:

  • @mussdroid 是的,这与我正在尝试的相同,但这里的问题是我在 RI 案例中的代码没有触发,即使我的输入流在打印到控制台时包含 RING RING 但如果相同的字符串与“RING”相比,它没有找到它,因此导致类似于 RI Case 没有以任何方式尝试提供帮助的情况。这是我在设置赏金后得到的第一个响应]
  • 这里需要的主要问题是解释 RI 事件没有触发因为我需要在进入应用程序的细节之前了解这一点

标签: java serial-port rxtx java-communication-api


【解决方案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;

【讨论】:

    【解决方案2】:

    请看看你的开关盒,你没有休息;那可能是个问题。

    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);
    • Dint 在我粘贴在这里的代码中出现了中断,由于其中还有其他代码而消失了,我在格式化以放入此页面时意外删除了它
    • 在您当前的代码中,您只在最后的情况下中断 SerialPortEvent.DATA_AVAILABLE: ,那么您在 serialPortEven.RI 情况下是否有中断?你仍然需要输入 if else 来查看它是打开还是关闭。
    • 所以让我问你一件事,即使其他事件未设置为真,如果 RI 事件是唯一设置为真的事件,即使中断 Println 应该可以正常工作?。但它不起作用。为什么强迫我发布这个问题。是的,在编辑期间将代码发布到这里之前,我实际上错过了
    • 是的,它从入口点执行,您可能需要检查程序是否进入switch case语句。
    猜你喜欢
    • 2011-10-13
    • 2011-07-26
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多