views:

57

answers:

2

hi,

Is it possible to send sms from windows machine to mobile phone.

I have searched a lot and got the following code.

Sender.java

package sms;

import java.util.Date;

public class Sender implements Runnable  {

  private static final long STANDARD=500;
  private static final long LONG=2000;
  private static final long  VERYLONG=20000;

  SerialConnection mySerial =null;

  static final private char cntrlZ=(char)26;
  String in, out;
  Thread aThread=null;
  private long delay=STANDARD;
  String recipient=null;
  String message=null;

  private String csca="+6596845999"; // the message center
  private SerialParameters defaultParameters= new SerialParameters ("COM2",9600,0,0,8,1,0);
  public int step;
  public int status=-1;
  public long messageNo=-1;

  public Sender(String recipient, String message){

    this.recipient=recipient;
    this.message=message;

  }
  /**
   * connect to the port and start the dialogue thread
   */
  public int send () throws Exception{

    SerialParameters params = defaultParameters;

    mySerial =new SerialConnection (params);

    mySerial.openConnection();

    aThread=new Thread(this);

    aThread.start() ;
    //log("start");

    return 0;
  }

  /**
   * implement the dialogue thread,
   * message / response via steps,
   * handle time out
   */

  public void run(){

    boolean timeOut=false;
    long startTime=(new Date()).getTime();



    while ((step <7) && (!timeOut)){
//      log(""+((new Date()).getTime() - startTime);
      //check where we are in specified delay
      timeOut=((new Date()).getTime() - startTime)>delay;

      //if atz does not work, type to send cntrlZ and retry, in case a message was stuck
      if (timeOut && (step==1)) {
          step=-1;
          mySerial.send(        ""+cntrlZ);
      }

      //read incoming string
      String result=  mySerial.getIncommingString() ;

//    log ("<- "+result+"\n--------");
      int expectedResult=-1;

      try{
        //log ("Step:"+step);

        switch (step){
          case 0:

            mySerial.send("atz");
            delay=LONG;
            startTime=(new Date()).getTime();
            break;

          case 1:
            delay=STANDARD;
            mySerial.send("ath0");
            startTime=(new Date()).getTime();
            break;
          case 2:
            expectedResult=result.indexOf("OK");

            //log ("received ok ="+expectedResult);
            if (expectedResult>-1){
              mySerial.send("at+cmgf=1");
              startTime=(new Date()).getTime();
            }else{
                step=step-1;
            }
            break;
          case 3:
            expectedResult=result.indexOf("OK");

           // log ("received ok ="+expectedResult);
            if (expectedResult>-1){
              mySerial.send("at+csca=\""+csca+"\"");
              startTime=(new Date()).getTime();
            }else{
              step=step-1;
            }

            break;
          case 4:
            expectedResult=result.indexOf("OK");

           // log ("received ok ="+expectedResult);
            if (expectedResult>-1){
              mySerial.send("at+cmgs=\""+recipient+"\"");
              startTime=(new Date()).getTime();
            }else{
              step=step-1;
            }

            break;
          case 5:
            expectedResult=result.indexOf(">");

           // log ("received ok ="+expectedResult);
            if (expectedResult>-1){
              mySerial.send(message+cntrlZ);
              startTime=(new Date()).getTime();
            }else{
              step=step-1;
            }
            delay=VERYLONG;//waitning for message ack

            break;

          case 6:
            expectedResult=result.indexOf("OK");
            //read message number
            if (expectedResult>-1){
              int n=result.indexOf("CMGS:");
              result=result.substring(n+5);
              n=result.indexOf("\n");
              status=0;
              messageNo=Long.parseLong(result.substring(0,n).trim() );

              log ("sent message no:"+messageNo);


            }else{
              step=step-1;
            }

          break;
        }
        step=step+1;

        aThread.sleep(100);

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

    mySerial.closeConnection() ;

    //if timed out set status

    if (timeOut ) {
        status=-2;
        log("*** time out at step "+step+"***");
    }
  }
/**
 * logging function, includes date and class name
 */
  private void log(String s){
    System.out.println (new java.util.Date()+":"+this.getClass().getName()+":"+s);
  }
}

SerialConnection.java

package sms;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;

import javax.comm.CommPortIdentifier;
import javax.comm.CommPortOwnershipListener;
import javax.comm.NoSuchPortException;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

/**
A class that handles the details of a serial connection. Reads from one
TextArea and writes to a second TextArea.
Holds the state of the connection.
*/
public class SerialConnection implements SerialPortEventListener,
      CommPortOwnershipListener {


    private SerialParameters parameters;
    private OutputStream os;
    private InputStream is;
    private KeyHandler keyHandler;

    private CommPortIdentifier portId;
    private SerialPort sPort;

    private boolean open;

    private String receptionString="";

    public String getIncommingString(){
      byte[] bVal= receptionString.getBytes();
      receptionString="";
      return new String (bVal);
  }


    public SerialConnection(SerialParameters parameters) {
        this.parameters = parameters;
 open = false;
   }

   /**
   Attempts to open a serial connection and streams using the parameters
   in the SerialParameters object. If it is unsuccesfull at any step it
   returns the port to a closed state, throws a
   <code>SerialConnectionException</code>, and returns.

   Gives a timeout of 30 seconds on the portOpen to allow other applications
   to reliquish the port if have it open and no longer need it.
   */
   public void openConnection() throws SerialConnectionException {

       // System.out.println("OK 0 ");
 // Obtain a CommPortIdentifier object for the port you want to open.

 try {
           // System.out.println(parameters.getPortName());
     portId = CommPortIdentifier.getPortIdentifier(parameters.getPortName());
 } catch (NoSuchPortException e) {
           // System.out.println("Yes the problem is here 1 ");
            e.printStackTrace();
    // throw new SerialConnectionException(e.getMessage());
 }catch(Exception e)
        {
          //  System.out.println("ErrorErrorErrorError");
            e.printStackTrace();
        }
        //System.out.println(portId);
        //System.out.println("OK 1 ");
 // Open the port represented by the CommPortIdentifier object. Give
 // the open call a relatively long timeout of 30 seconds to allow
 // a different application to reliquish the port if the user
 // wants to.
 try {
     sPort = (SerialPort)portId.open("SMSConnector", 30000);
 } catch (PortInUseException e) {

     throw new SerialConnectionException(e.getMessage());
 }
        //System.out.println("OK 2 ");
        sPort.sendBreak(1000);

 // Set the parameters of the connection. If they won't set, close the
 // port before throwing an exception.
 try {
     setConnectionParameters();
 } catch (SerialConnectionException e) {
     sPort.close();
     throw e;
 }
       // System.out.println("OK 3 ");
 // Open the input and output streams for the connection. If they won't
 // open, close the port before throwing an exception.
 try {
     os = sPort.getOutputStream();
     is = sPort.getInputStream();
 } catch (IOException e) {
     sPort.close();
     throw new SerialConnectionException("Error opening i/o streams");
 }
//System.out.println("OK 4 ");
/*
 // Create a new KeyHandler to respond to key strokes in the
 // messageAreaOut. Add the KeyHandler as a keyListener to the
 // messageAreaOut.
 keyHandler = new KeyHandler(os);
 messageAreaOut.addKeyListener(keyHandler);
*/
 // Add this object as an event listener for the serial port.
 try {
     sPort.addEventListener(this);
 } catch (TooManyListenersException e) {
     sPort.close();
     throw new SerialConnectionException("too many listeners added");
 }
//System.out.println("OK 5 ");
 // Set notifyOnDataAvailable to true to allow event driven input.
 sPort.notifyOnDataAvailable(true);

 // Set notifyOnBreakInterrup to allow event driven break handling.
 sPort.notifyOnBreakInterrupt(true);

 // Set receive timeout to allow breaking out of polling loop during
 // input handling.
 try {
     sPort.enableReceiveTimeout(30);
 } catch (UnsupportedCommOperationException e) {
 }
//System.out.println("OK 6 ");
 // Add ownership listener to allow ownership event handling.
 portId.addPortOwnershipListener(this);

 open = true;
    }

    /**
    Sets the connection parameters to the setting in the parameters object.
    If set fails return the parameters object to origional settings and
    throw exception.
    */
    public void setConnectionParameters() throws SerialConnectionException {

 // Save state of parameters before trying a set.
 int oldBaudRate = sPort.getBaudRate();
 int oldDatabits = sPort.getDataBits();
 int oldStopbits = sPort.getStopBits();
 int oldParity   = sPort.getParity();
 int oldFlowControl = sPort.getFlowControlMode();

 // Set connection parameters, if set fails return parameters object
 // to original state.
 try {
     sPort.setSerialPortParams(parameters.getBaudRate(),
          parameters.getDatabits(),
          parameters.getStopbits(),
          parameters.getParity());
 } catch (UnsupportedCommOperationException e) {
     parameters.setBaudRate(oldBaudRate);
     parameters.setDatabits(oldDatabits);
     parameters.setStopbits(oldStopbits);
     parameters.setParity(oldParity);
     throw new SerialConnectionException("Unsupported parameter");
 }

 // Set flow control.
 try {
     sPort.setFlowControlMode(parameters.getFlowControlIn()
              | parameters.getFlowControlOut());
 } catch (UnsupportedCommOperationException e) {
     throw new SerialConnectionException("Unsupported flow control");
 }
    }

    /**
    Close the port and clean up associated elements.
    */
    public void closeConnection() {
 // If port is alread closed just return.
 if (!open) {
     return;
 }

 // Remove the key listener.
// messageAreaOut.removeKeyListener(keyHandler);

 // Check to make sure sPort has reference to avoid a NPE.
 if (sPort != null) {
     try {
  // close the i/o streams.
      os.close();
      is.close();
     } catch (IOException e) {
  System.err.println(e);
     }

     // Close the port.
     sPort.close();

     // Remove the ownership listener.
     portId.removePortOwnershipListener(this);
 }

 open = false;
    }

    /**
    Send a one second break signal.
    */
    public void sendBreak() {
 sPort.sendBreak(1000);
    }

    /**
    Reports the open status of the port.
    @return true if port is open, false if port is closed.
    */
    public boolean isOpen() {
 return open;
    }

    /**
    Handles SerialPortEvents. The two types of SerialPortEvents that this
    program is registered to listen for are DATA_AVAILABLE and BI. During
    DATA_AVAILABLE the port buffer is read until it is drained, when no more
    data is availble and 30ms has passed the method returns. When a BI
    event occurs the words BREAK RECEIVED are written to the messageAreaIn.
    */

    public void serialEvent(SerialPortEvent e) {
  // Create a StringBuffer and int to receive input data.
 StringBuffer inputBuffer = new StringBuffer();
 int newData = 0;

 // Determine type of event.

 switch (e.getEventType()) {

     // Read data until -1 is returned. If \r is received substitute
     // \n for correct newline handling.
     case SerialPortEvent.DATA_AVAILABLE:
      while (newData != -1) {
       try {
           newData = is.read();
       if (newData == -1) {
    break;
       }
       if ('\r' == (char)newData) {
       inputBuffer.append('\n');
       } else {
        inputBuffer.append((char)newData);
       }
       } catch (IOException ex) {
           System.err.println(ex);
           return;
         }
         }

  // Append received data to messageAreaIn.
  receptionString=receptionString+ (new String(inputBuffer));
                //System.out.print("<-"+receptionString);
  break;

     // If break event append BREAK RECEIVED message.
     case SerialPortEvent.BI:
  receptionString=receptionString+("\n--- BREAK RECEIVED ---\n");
 }

    }

    /**
    Handles ownership events. If a PORT_OWNERSHIP_REQUESTED event is
    received a dialog box is created asking the user if they are
    willing to give up the port. No action is taken on other types
    of ownership events.
    */
    public void ownershipChange(int type) {
      /*
 if (type == CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED) {
     PortRequestedDialog prd = new PortRequestedDialog(parent);
 }
        */
    }

    /**
    A class to handle <code>KeyEvent</code>s generated by the messageAreaOut.
    When a <code>KeyEvent</code> occurs the <code>char</code> that is
    generated by the event is read, converted to an <code>int</code> and
    writen to the <code>OutputStream</code> for the port.
    */
    class KeyHandler extends KeyAdapter {
 OutputStream os;

 /**
 Creates the KeyHandler.
 @param os The OutputStream for the port.
 */
 public KeyHandler(OutputStream os) {
     super();
     this.os = os;
 }

 /**
 Handles the KeyEvent.
 Gets the <code>char</char> generated by the <code>KeyEvent</code>,
 converts it to an <code>int</code>, writes it to the <code>
 OutputStream</code> for the port.
 */
        public void keyTyped(KeyEvent evt) {
            char newCharacter = evt.getKeyChar();
            if ((int)newCharacter==10) newCharacter = '\r';
            System.out.println ((int)newCharacter);
     try {
      os.write((int)newCharacter);
     } catch (IOException e) {
  System.err.println("OutputStream write error: " + e);
     }
        }
    }
        public void send(String message) {
            byte[] theBytes= (message+"\n").getBytes();
            for (int i=0; i<theBytes.length;i++){

              char newCharacter = (char)theBytes[i];
              if ((int)newCharacter==10) newCharacter = '\r';

       try {
      os.write((int)newCharacter);
              } catch (IOException e) {
                  System.err.println("OutputStream write error: " + e);
              }

            }
            //System.out.println (">'" +message +"' sent");




        }
}

SerialConnection.java

package sms;

public class SerialConnectionException extends Exception {

    /**
     * Constructs a <code>SerialConnectionException</code>
     * with the specified detail message.
     *
     * @param   s   the detail message.
     */
    public SerialConnectionException(String str) {
        super(str);
    }

    /**
     * Constructs a <code>SerialConnectionException</code>
     * with no detail message.
     */
    public SerialConnectionException() {
        super();
    }
}

SerialParameters.java

package sms;
import javax.comm.SerialPort;

/**
A class that stores parameters for serial ports.
*/
public class SerialParameters {

    private String portName;
    private int baudRate;
    private int flowControlIn;
    private int flowControlOut;
    private int databits;
    private int stopbits;
    private int parity;

    /**
    Default constructer. Sets parameters to no port, 9600 baud, no flow
    control, 8 data bits, 1 stop bit, no parity.
    */
    public SerialParameters () {
 this("",
      9600,
      SerialPort.FLOWCONTROL_NONE,
      SerialPort.FLOWCONTROL_NONE,
      SerialPort.DATABITS_8,
      SerialPort.STOPBITS_1,
      SerialPort.PARITY_NONE );

    }

    /**
    Paramaterized constructer.

    @param portName The name of the port.
    @param baudRate The baud rate.
    @param flowControlIn Type of flow control for receiving.
    @param flowControlOut Type of flow control for sending.
    @param databits The number of data bits.
    @param stopbits The number of stop bits.
    @param parity The type of parity.
    */
    public SerialParameters(String portName,
       int baudRate,
       int flowControlIn,
       int flowControlOut,
       int databits,
       int stopbits,
       int parity) {

     this.portName = portName;
     this.baudRate = baudRate;
     this.flowControlIn = flowControlIn;
     this.flowControlOut = flowControlOut;
     this.databits = databits;
     this.stopbits = stopbits;
     this.parity = parity;
    }

    /**
    Sets port name.
    @param portName New port name.
    */
    public void setPortName(String portName) {
 this.portName = portName;
    }

    /**
    Gets port name.
    @return Current port name.
    */
    public String getPortName() {
 return portName;
    }

    /**
    Sets baud rate.
    @param baudRate New baud rate.
    */
    public void setBaudRate(int baudRate) {
 this.baudRate = baudRate;
    }

    /**
    Sets baud rate.
    @param baudRate New baud rate.
    */
    public void setBaudRate(String baudRate) {
 this.baudRate = Integer.parseInt(baudRate);
    }

    /**
    Gets baud rate as an <code>int</code>.
    @return Current baud rate.
    */
    public int getBaudRate() {
 return baudRate;
    }

    /**
    Gets baud rate as a <code>String</code>.
    @return Current baud rate.
    */
    public String getBaudRateString() {
 return Integer.toString(baudRate);
    }

    /**
    Sets flow control for reading.
    @param flowControlIn New flow control for reading type.
    */
    public void setFlowControlIn(int flowControlIn) {
 this.flowControlIn = flowControlIn;
    }

    /**
    Sets flow control for reading.
    @param flowControlIn New flow control for reading type.
    */
    public void setFlowControlIn(String flowControlIn) {
 this.flowControlIn = stringToFlow(flowControlIn);
    }

    /**
    Gets flow control for reading as an <code>int</code>.
    @return Current flow control type.
    */
    public int getFlowControlIn() {
 return flowControlIn;
    }

    /**
    Gets flow control for reading as a <code>String</code>.
    @return Current flow control type.
    */
    public String getFlowControlInString() {
 return flowToString(flowControlIn);
    }

    /**
    Sets flow control for writing.
    @param flowControlIn New flow control for writing type.
    */
    public void setFlowControlOut(int flowControlOut) {
 this.flowControlOut = flowControlOut;
    }

    /**
    Sets flow control for writing.
    @param flowControlIn New flow control for writing type.
    */
    public void setFlowControlOut(String flowControlOut) {
 this.flowControlOut = stringToFlow(flowControlOut);
    }

    /**
    Gets flow control for writing as an <code>int</code>.
    @return Current flow control type.
    */
    public int getFlowControlOut() {
 return flowControlOut;
    }

    /**
    Gets flow control for writing as a <code>String</code>.
    @return Current flow control type.
    */
    public String getFlowControlOutString() {
 return flowToString(flowControlOut);
    }

    /**
    Sets data bits.
    @param databits New data bits setting.
    */
    public void setDatabits(int databits) {
 this.databits = databits;
    }

    /**
    Sets data bits.
    @param databits New data bits setting.
    */
    public void setDatabits(String databits) {
 if (databits.equals("5")) {
     this.databits = SerialPort.DATABITS_5;
 }
 if (databits.equals("6")) {
     this.databits = SerialPort.DATABITS_6;
 }
 if (databits.equals("7")) {
     this.databits = SerialPort.DATABITS_7;
 }
 if (databits.equals("8")) {
     this.databits = SerialPort.DATABITS_8;
 }
    }

    /**
    Gets data bits as an <code>int</code>.
    @return Current data bits setting.
    */
    public int getDatabits() {
 return databits;
    }

    /**
    Gets data bits as a <code>String</code>.
    @return Current data bits setting.
    */
    public String getDatabitsString() {
 switch(databits) {
     case SerialPort.DATABITS_5:
  return "5";
     case SerialPort.DATABITS_6:
  return "6";
     case SerialPort.DATABITS_7:
  return "7";
     case SerialPort.DATABITS_8:
  return "8";
     default:
  return "8";
 }
    }

    /**
    Sets stop bits.
    @param stopbits New stop bits setting.
    */
    public void setStopbits(int stopbits) {
 this.stopbits = stopbits;
    }

    /**
    Sets stop bits.
    @param stopbits New stop bits setting.
    */
    public void setStopbits(String stopbits) {
 if (stopbits.equals("1")) {
     this.stopbits = SerialPort.STOPBITS_1;
 }
 if (stopbits.equals("1.5")) {
     this.stopbits = SerialPort.STOPBITS_1_5;
 }
 if (stopbits.equals("2")) {
     this.stopbits = SerialPort.STOPBITS_2;
 }
    }

    /**
    Gets stop bits setting as an <code>int</code>.
    @return Current stop bits setting.
    */
    public int getStopbits() {
 return stopbits;
    }

    /**
    Gets stop bits setting as a <code>String</code>.
    @return Current stop bits setting.
    */
    public String getStopbitsString() {
 switch(stopbits) {
     case SerialPort.STOPBITS_1:
  return "1";
     case SerialPort.STOPBITS_1_5:
  return "1.5";
     case SerialPort.STOPBITS_2:
  return "2";
     default:
  return "1";
 }
    }

    /**
    Sets parity setting.
    @param parity New parity setting.
    */
    public void setParity(int parity) {
 this.parity = parity;
    }

    /**
    Sets parity setting.
    @param parity New parity setting.
    */
    public void setParity(String parity) {
 if (parity.equals("None")) {
     this.parity = SerialPort.PARITY_NONE;
 }
 if (parity.equals("Even")) {
     this.parity = SerialPort.PARITY_EVEN;
 }
 if (parity.equals("Odd")) {
     this.parity = SerialPort.PARITY_ODD;
 }
    }

    /**
    Gets parity setting as an <code>int</code>.
    @return Current parity setting.
    */
    public int getParity() {
 return parity;
    }

    /**
    Gets parity setting as a <code>String</code>.
    @return Current parity setting.
    */
    public String getParityString() {
 switch(parity) {
     case SerialPort.PARITY_NONE:
  return "None";
      case SerialPort.PARITY_EVEN:
  return "Even";
     case SerialPort.PARITY_ODD:
  return "Odd";
     default:
  return "None";
 }
    }

    /**
    Converts a <code>String</code> describing a flow control type to an
    <code>int</code> type defined in <code>SerialPort</code>.
    @param flowControl A <code>string</code> describing a flow control type.
    @return An <code>int</code> describing a flow control type.
    */
    private int stringToFlow(String flowControl) {
 if (flowControl.equals("None")) {
     return SerialPort.FLOWCONTROL_NONE;
 }
 if (flowControl.equals("Xon/Xoff Out")) {
     return SerialPort.FLOWCONTROL_XONXOFF_OUT;
 }
 if (flowControl.equals("Xon/Xoff In")) {
     return SerialPort.FLOWCONTROL_XONXOFF_IN;
 }
 if (flowControl.equals("RTS/CTS In")) {
     return SerialPort.FLOWCONTROL_RTSCTS_IN;
 }
 if (flowControl.equals("RTS/CTS Out")) {
     return SerialPort.FLOWCONTROL_RTSCTS_OUT;
 }
 return SerialPort.FLOWCONTROL_NONE;
    }

    /**
    Converts an <code>int</code> describing a flow control type to a
    <code>String</code> describing a flow control type.
    @param flowControl An <code>int</code> describing a flow control type.
    @return A <code>String</code> describing a flow control type.
    */
    String flowToString(int flowControl) {
 switch(flowControl) {
     case SerialPort.FLOWCONTROL_NONE:
  return "None";
     case SerialPort.FLOWCONTROL_XONXOFF_OUT:
  return "Xon/Xoff Out";
     case SerialPort.FLOWCONTROL_XONXOFF_IN:
  return "Xon/Xoff In";
     case SerialPort.FLOWCONTROL_RTSCTS_IN:
  return "RTS/CTS In";
     case SerialPort.FLOWCONTROL_RTSCTS_OUT:
  return "RTS/CTS Out";
     default:
  return "None";
 }
    }
}

But when i am trying to run the code, i am getting following error:-

Error loading SolarisSerial: java.lang.UnsatisfiedLinkError: no SolarisSerialParallel in java.library.path
Caught java.lang.UnsatisfiedLinkError: com.sun.comm.SolarisDriver.readRegistrySerial(Ljava/util/Vector;Ljava/lang/String;)I while loading driver com.sun.comm.SolarisDriver

is this code that i have taken OS specific. Or there are any other way to send sms(txt) from pc to mobile.

Please help me.

A: 

Your code relies on a JNI driver class "com.sun.comm.SolarisDriver". Your program can't locate the dinamic library SolarisSerialParallel.

The Java virtual machine needs to be able to find the native library. To do this, set the library path adding the path to the library as follows:

Unix or Linux based systems:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH;'/opt/whatever/SolarisSerialParallel.so'
export LD_LIBRARY_PATH

Windows (I guess that in this case, you'll need to search the appropiate DLL, as the one required at your question seems to be exclusive for Solaris environments):

set PATH=%path%;C:\whatever\SolarisSerialParallel.dll

Note that you can point it to the containing directory, if more libraries ar needed.

Reference: Java Native Interface Specification

Tomas Narros
A: 

I think this is a very complicated approach. If you are developing a commercial application, there are many companies which provide web services that you could use. You just send the sms text to the webservice, and they will send the sms for you, no need to reinvent the wheel. Unless you are developing a webservice like this yourself!

Amr Hesham Abdel Majeed