短信积分商城 400-6699-521 咨询热线: 0371-69067686
行业动态Industry Dynamics
您的位置: 首页 > 乐信行业动态 >
Java发送手机短信的方法及程序源代码
  Java发送手机短信需要什么呢?如何通过Java程序实现群发手机短信呢?下面乐信短信平台小编通过以下方法实现java发送手机短信。用 Java 通过串口发短信其实很简单,因为有现成的类库供我们 使用。有底层的类库,也有封装好一点的类库,下面我介绍一下在 Win32 平台下发送短信的方法。
  如果你想用更底层的类库开发功能更强大的应用程序有两种选择:一个是 SUN Java Comm(下载地址:javacomm20-win32.zip),另一个是 RxTx (下载地址:Rxtx.zip)
  用这两个类库开发程序的先决条件是你要很好掌握串口的知识,比如 AT 命令等,这些基本知识学起来是需要一定时间的,不过不用担心,现在也有开源的已经封装好的类库供我们使用,这就是  SMSLib - SMS Processing Libraries (下载地址:SMSLib),今后的几篇系列文章主要目的就是介绍 SMSLib 的使用,今天首先就是要安装环境了,注意最新的 SMSLib 只能在 JRE5.0 或以后的版本才 能运行。
  SMSLib 也是构建在 SUN Java Comm 和 RxTx 基础之上的,这两个类库你可以自己选择,不过 SMSLib 默认采用的是 SUN Java Comm(即你下载下来的 SMSLib 包中的 dist\lib 目录下的 smslib- 2.1.2.jar 是用 SUN Java Comm 编译生成的),
  如果你想更换成 RxTx 就需要更改 SMSLib 的源文件并重新编译,具体方法为:
  将 src\java\org\smslib 文件夹下的 CSerialDriver.java 这个文件的 "import javax.comm.*;" 修改为 "import gnu.io.*;",然后用 ant 工具重新编译生成的 jar 文件就是基于 RxTx 实现的 。
  下面介绍一下 SUN Java Comm 和 RxTx 的安装过程:
  ①. SUN Java Comm:
  将 "javax.comm.properties" 拷贝到 "%JREHOME%/lib" 目录下
  将 "win32com.dll" 拷贝到 "%JREHOME%/bin" 目录下
  ②. RxTx
  将 "rxtxSerial.dll" 拷贝到 "%JREHOME%/bin" 目录下
  然后将 "comm.jar" 或者 "RXTXComm.jar" 加载到你的工程环境中就可以了,另外还要记着下载 log4j,因为 SMSLib 用到了它。
  如果对串口有兴趣的朋友可以去研究一下 AT 命令,直接使用 SUN Java Comm 和 RxTx 编写应用程序,可以实现更强大的功能。
  在开发手机短信开发之前,需要下载JAVA的串口访问接口类包
  我先到SUN的网站 ,只找到了版本Java(tm) Communication API 3.0 Update 1 for Solaris x86  和 Solaris 8 & 9 -Sparc 和 Linux,没有找到WINDOWS平台的。后来在 http://www.matrix.org.cn/thread.shtml?topicId=37246&forumId=1找到了Java(tm) Communication API 2.0WINDOWS平台的版本。在下载解压将其添加到LIB中,然后就可以开始手机短信的开发了。
  java发送手机短信源代码:
  ReadSerial类
  package com.nlie.pub_com.msgmgr;
  import java.io.*;
  /**
  *
  * This class reads message from the specific serial port and save
  * the message to the serial buffer.
  *
  */
  public class ReadSerial
  extends Thread {
  private SerialBuffer ComBuffer;
  private InputStream ComPort;
  /**
  *
  * Constructor
  *
  * @param SB The buffer to save the incoming messages.
  * @param Port The InputStream from the specific serial port.
  *
  */
  public ReadSerial(SerialBuffer SB, InputStream Port) {
  ComBuffer = SB;
  ComPort = Port;
  }
  public void run() {
  int c;
  try {
  while (true) {
  c = ComPort.read();
  ComBuffer.PutChar(c);
  }
  }
  catch (IOException e) {}
  }
  }
  SerialBean类
  package com.nlie.pub_com.msgmgr;
  import java.io.*;
  import java.util.*;
  import javax.comm.*;
  /**
  *
  * This bean provides some basic functions to implement full dulplex
  * information exchange through the srial port.
  *
  */
  public class SerialBean {
  static String PortName;
  CommPortIdentifier portId;
  SerialPort serialPort;
  static OutputStream out;
  static InputStream in;
  SerialBuffer SB;
  ReadSerial RT;
  /**
  *
  * Constructor
  *
  * @param PortID the ID of the serial to be used. 1 for COM1,
  * 2 for COM2, etc.
  *
  */
  public SerialBean(int PortID) {
  PortName = "COM" + PortID;
  }
  /**
  *
  * This function initialize the serial port for communication. It starts a
  * thread which consistently monitors the serial port. Any signal captured
  * from the serial port is stored into a buffer area.
  *
  */
  public int Initialize() {
  int InitSuccess = 1;
  int InitFail = -1;
  try {
  portId = CommPortIdentifier.getPortIdentifier(PortName);
  try {
  serialPort = (SerialPort)
  portId.open("Serial_Communication", 2000);
  }
  catch (PortInUseException e) {
  return InitFail;
  }
  //Use InputStream in to read from the serial port, and OutputStream
  //out to write to the serial port.
  try {
  in = serialPort.getInputStream();
  out = serialPort.getOutputStream();
  }
  catch (IOException e) {
  return InitFail;
  }
  //Initialize the communication parameters to 9600, 8, 1, none.
  try {
  serialPort.setSerialPortParams(9600,
  SerialPort.DATABITS_8,
  SerialPort.STOPBITS_1,
  SerialPort.PARITY_NONE);
  }
  catch (UnsupportedCommOperationException e) {
  return InitFail;
  }
  }
  catch (NoSuchPortException e) {
  return InitFail;
  }
  // when successfully open the serial port, create a new serial buffer,
  // then create a thread that consistently accepts incoming signals from
  // the serial port. Incoming signals are stored in the serial buffer.
  SB = new SerialBuffer();
  RT = new ReadSerial(SB, in);
  RT.start();
  // return success information
  return InitSuccess;
  }
  /**
  *
  * This function returns a string with a certain length from the incoming
  * messages.
  *
  * @param Length The length of the string to be returned.
  *
  */
  public String ReadPort(int Length) {
  String Msg;
  Msg = SB.GetMsg(Length);
  return Msg;
  }
  /**
  *
  * This function sends a message through the serial port.
  *
  * @param Msg The string to be sent.
  *
  */
  public void WritePort(String Msg) {
  int c;
  try {
  for (int i = 0; i < Msg.length(); i++) {
  out.write(Msg.charAt(i));
  }
  }
  catch (IOException e) {}
  }
  /**
  *
  * This function closes the serial port in use.
  *
  */
  public void ClosePort() {
  RT.stop();
  serialPort.close();
  }
  }
  SerialBuffer类
  package com.nlie.pub_com.msgmgr;
  public class SerialBuffer {
  private String Content = "";
  private String CurrentMsg, TempContent;
  private boolean available = false;
  private int LengthNeeded = 1;
  /**
  *
  * This function returns a string with a certain length from the incoming
  * messages.
  *
  * @param Length The length of the string to be returned.
  *
  */
  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;
  }
  /**
  *
  * This function stores a character captured from the serial port to the
  * buffer area.
  *
  * @param t The char value of the character to be stored.
  *
  */
  public synchronized void PutChar(int c) {
  Character d = new Character( (char) c);
  Content = Content.concat(d.toString());
  if (LengthNeeded < Content.length()) {
  available = true;
  }
  notifyAll();
  }
  }
  mobi_operate_bean类
  package com.nlie.pub_com.msgmgr;
  public class mobi_operate_bean
  extends Thread {
  private boolean be_send = false;
  private static char symbol = 10;
  private static char symbol1 = 13;
  private static SerialBean SB = null;
  /*
  private String message_cont = null;
  private String sms_send_no = null;
  public void setmessage_cont(String strsmscont) {
  message_cont = strsmscont;
  }
  public void setsms_send_no(String strsms_send_no) {
  sms_send_no = strsms_send_no;
  }
  public String getmessage_cont() {
  return message_cont;
  }
  public String getsms_send_no() {
  return sms_send_no;
  }
  */
  //************************************************************
  //函数名:delete_sms(int SmsNo,int DelFlag)
  //参数说明
  //smsNo:需要删除的短消息序号
  //DelFlag:删除标记 0 为当前序号 1 所有读过的记录 2 所有读过和发送的记录
  //        3 所有读过和发送和未发送的记录 4 所有短消息
  //作者:乐信
  //时间:2002年4月14日
  public static boolean delete_sms(int SmsNo, int DelFlag) {
  String strReturn, strSend;
  strReturn = "";
  strSend = "";
  try {
  strSend = "AT+CMGD=" + String.valueOf(DelFlag) + String.valueOf(symbol) +
  String.valueOf(symbol1);
  SB.WritePort(strSend);
  sleep(200);
  strReturn = SB.ReadPort(10);
  if (strReturn.indexOf("OK", 0) != -1) {
  return true;
  }
  return false;
  }
  catch (Exception ex) {
  ex.printStackTrace();
  return false;
  }
  }
  //************************************************************
  //函数名:opencomm(int commport)
  //参数说明
  //commport:需要打开的串口号
  //返回:
  //   false  打开串口失败
  //   true   打开串口成功
  //作者:乐信
  //时间:2002年4月14日
  public static boolean opencomm(int commport) {
  SB = new SerialBean(commport);
  if (SB.Initialize() == 1) {
  return true;
  }
  else {
  return false;
  }
  }
  //************************************************************
  //函数名:testmobi
  //参数说明
  //
  //返回:
  //   false  测试失败
  //   true   测试成功
  //作者:乐信
  //时间:2002年4月14日
  public static boolean testmobi() {
  String strReturn, strSend;
  strReturn = "";
  strSend = "";
  strSend = "AT" + String.valueOf(symbol1);
  try {
  SB.WritePort(strSend);
  sleep(200);
  strReturn = SB.ReadPort(9);
  if (strReturn.indexOf("OK", 0) != -1) {
  strSend = "ATE0" + String.valueOf(symbol1);
  SB.WritePort(strSend);
  strReturn = "";
  sleep(200);
  strReturn = SB.ReadPort(11);
  if (strReturn.indexOf("OK", 0) != -1) {
  return true;
  }
  }
  return false;
  }
  catch (Exception ex) {
  ex.printStackTrace();
  return false;
  }
  }
  //************************************************************
  //函数名:setmode(int mode)
  //参数说明
  //mode:短信发送模式
  //返回说明:
  //      false   设置模式失败
  //      true    设置模式成功
  //作者:乐信
  //时间:2002年4月14日
  private static boolean setmode(int mode) {
  String strReturn, strSend;
  strSend = "";
  try {
  strSend = "AT+CMGF=" + String.valueOf(mode) +
  String.valueOf(symbol1);
  SB.WritePort(strSend);
  strReturn = "";
  sleep(200);
  strReturn = SB.ReadPort(6);
  if (strReturn.indexOf("OK", 0) != -1) {
  return true;
  }
  return false;
  }
  catch (Exception ex) {
  ex.printStackTrace();
  return false;
  }
  }
  //************************************************************
  //函数名:sendMessage
  //参数说明
  //   Receiver:短信接收者的手机号码
  //   sms_content:短信内容
  //返回:
  //   false  发送失败
  //   true   发送成功
  //作者:乐信
  //时间:2002年4月14日
  public static boolean sendMessage(String Receiver, String sms_content) {
  String strReturn, strSend;
  char symbol2 = 34;
  char symbol3 = 26;
  strReturn = "";
  strSend = "";
  if (setmode(1) != true) {
  return false;
  }
  try {
  strSend = "AT+CSMP=1,173,36,08" + String.valueOf(symbol1);
  System.out.println("step 1 begin");
  SB.WritePort(strSend);
  sleep(400);
  strReturn = SB.ReadPort(6);
  if (strReturn.indexOf("OK", 0) != -1) {
  System.out.println("step 1 ok");
  strSend = "AT+CMGS=" + String.valueOf(symbol2) + Receiver +
  String.valueOf(symbol2) +
  String.valueOf(symbol1);
  System.out.println("step 2 begin");
  SB.WritePort(strSend);
  strReturn = "";
  sleep(200);
  strReturn = SB.ReadPort(4);
  System.out.println("step 3 begin");
  byte[] str1 = null;
  try {
  str1 = sms_content.getBytes("GBK");
  }
  catch (java.io.UnsupportedEncodingException e) {
  e.printStackTrace();
  }
  strSend = encodeHex(str1, sms_content) + String.valueOf(symbol3) +
  String.valueOf(symbol1);
  strReturn = "";
  System.out.println("step 4 begin");
  SB.WritePort(strSend);
  sleep(2000);
  strReturn = "";
  strReturn = SB.ReadPort(8);
  if (strReturn.indexOf("+CMGS", 0) != -1) {
  System.out.println("OK");
  return true;
  }
  }
  return false;
  }
  catch (Exception ex) {
  ex.printStackTrace();
  return false;
  }
  }
  //************************************************************
  //函数名:getMessage
  //参数说明
  //   Way:短信接收者的手机号码
  //   m_Mode:短信内容
  //返回:
  //   false  发送失败
  //   true   发送成功
  //作者:乐信
  //时间:2002年1月5日
  public static String getMessage(int Way, int m_Mode) {
  String strReturn, strSend;
  strReturn = "";
  strSend = "";
  String strtemp = null;
  if (m_Mode == 0) {
  switch (Way) {
  case 0:
  strtemp = "REC UNREAD";
  break;
  case 1:
  strtemp = "REC READ";
  break;
  case 2:
  strtemp = "STO UNSENT";
  break;
  case 3:
  strtemp = "STO SENT";
  break;
  case 4:
  strtemp = "ALL";
  break;
  }
  }
  else {
  switch (Way) {
  case 0:
  strtemp = "REC UNREAD";
  break;
  case 1:
  strtemp = "REC READ";
  break;
  case 2:
  strtemp = "STO UNSENT";
  break;
  case 3:
  strtemp = "STO SENT";
  break;
  case 4:
  strtemp = "ALL";
  break;
  }
  }
  try {
  strSend = "AT+CMGL=" + strtemp + String.valueOf(symbol1);
  SB.WritePort(strSend);
  strReturn = SB.ReadPort(256);
  if (strReturn.indexOf("OK", 0) != -1) {
  if (strReturn.indexOf("+CMGL", 0) != -1) {
  int i = strReturn.indexOf(":");
  strtemp = strReturn.substring(i, strReturn.length());
  return strtemp;
  }
  }
  return null;
  }
  catch (Exception ex) {
  ex.printStackTrace();
  return null;
  }
  }
  public mobi_operate_bean() {
  }
  //************************************************************
  //函数名:encodeHex
  //参数说明
  //   bytes:短信内容BYTE值
  //   sms_content:短信内容
  //返回:
  //   返回解码的PDU格式短信内容
  //
  //作者:乐信
  //时间:2002年1月5日
  private static final String encodeHex(byte[] bytes, String sms_content) {
  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 = sms_content.charAt( (i - n) / 2 + n);
  m = a;
  b = Integer.toHexString(m);
  buff.append(b.substring(0, 4));
  i = i + 1;
  }
  }
  return buff.toString();
  }
  public static void main(String[] args) {
  mobi_operate_bean.opencomm(3);
  mobi_operate_bean.testmobi();
  // String smscont = mobi_operate_bean.getMessage(1, 2);
  mobi_operate_bean.sendMessage("186********",
  "乐信短信平台,高效优质的群发短信平台,采用短信发送成功计费、失败返款的模式,为企业提供企信通短信平台、企业短信、网页短信群发平台等移动商务的行业方案整合服务。");
  }
  }

(责任编辑:乐信企信通)