手机蓝牙通信设计(三) RFCOMM协议客户端+语音传送与接收

最近作相关蓝牙RFCOMM协议的东西,下面类主要是针对蓝牙串口协议的客户端,其中包含了设备的搜索,服务的搜索,以及MMAPI函数的应用,希望通过这个类,能让初学者掌握基本的设备的搜索,服务的搜索,和蓝牙串口协议以及录音和语音发送播放等:
注意HelloMidlet midlet为一个基础设计的界面类,用来调用ClientBox 类

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.*;

import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;

//jsr082 API
import javax.bluetooth.BluetoothStateException;

import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import hello.HelloMidlet;
import java.io.InputStream; //
import javax.microedition.media.*;
import javax.bluetooth.DataElement;

/**
 * 客户端GUI
 */
public class ClientBox  extends Form implements Runnable, CommandListener, DiscoveryListener {

  //字串输入框
  TextField input = new TextField("开始搜索", "", 100, TextField.ANY); //编辑框
  Command com_1 = new Command("开始通话", Command.SCREEN, 0);
  Command com_2 = new Command("停止通话", Command.SCREEN, 0);
 // StringItem result = new StringItem("", "");

  private DiscoveryAgent discoveryAgent;

  StreamConnection conn;

  private UUID[] uuidSet;

  //响应服务的UUID
  //GUID
  private static final UUID ECHO_SERVER_UUID = new UUID( "000050020000100080000002ee000001", false);
  //private static final UUID ECHO_SERVER_UUID = new UUID( "F0E0D0C0B0A000908070605040302010", true);
  private static final int[] attrSet = {0x0100};//return service name attribute
  //相应通话按钮的实例
   private PrimeThread mainThread;

 
  //设备集合

  Vector devices = new Vector();

  //服务集合

  Vector records = new Vector();

  //服务搜索的事务id集合

  int[] transIDs;

  HelloMidlet midlet;

  public ClientBox(hello.HelloMidlet midlet) {

    super("");

    this.midlet = midlet;

    //this.append(result);

    this.addCommand(new Command("取消", Command.EXIT, 1));
    this.addCommand(com_1);
    this.addCommand(com_2);
    this.append(input);

    this.setCommandListener(this);

     new Thread(this).start();

  }

  public void commandAction(Command arg0, Displayable arg1) {

    if (arg0.getCommandType() == Command.EXIT) {
        if( mainThread!=null)
              mainThread.distroy();
     this.midlet.exitMIDlet(); //midlet.showMainMenu();
    }
    else if (arg0 == com_1) { 
        input.setString("通话开始");
      Thread fetchThread = new Thread() {

        public void run() {

          for (int i = 0; i < records.size(); i++) {

            ServiceRecord sr = (ServiceRecord) records.elementAt(i);
            javax.bluetooth.DataElement de = (DataElement)sr.getAttributeValue(0x0100);
            String serverName = (String)de.getValue();
            /*
            if(serverName.compareTo("CKCService") < 0) {
                continue ;
            } else if (serverName.compareTo("CKCService") > 0)
            {} else {}
            
             if( !serverName.equals("CKCService") ){
                continue ;
             }
           */
            if (accessService(sr)) {
              break;
            }
          }
        }
      };
      fetchThread.start();
    }  else {
        if(mainThread != null){
            mainThread.distroy();
        }
        input.setString("通话结束");
    }
  }
  private boolean accessService(ServiceRecord sr) {

    boolean result = false;
    try {
          String url = sr.getConnectionURL(
          ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
          conn = (StreamConnection) Connector.open(url); //
          mainThread = new PrimeThread(conn,this);
          mainThread.start();
          result = true;
        }
        catch (IOException e) {
        }
    return result;
  }
  public void showInfo( String s) {
      this.input.setString(s);
  }
  public synchronized void run() {
    //发现设备和服务的过程中,给用户以Gauge
    Gauge g = new Gauge(null, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING);
    this.append(g);
    showInfo("蓝牙初始化...");
    boolean isBTReady = false;

    try {

      LocalDevice localDevice = LocalDevice.getLocalDevice();
      discoveryAgent = localDevice.getDiscoveryAgent();

      isBTReady = true;
    }
    catch (Exception e) {         
      e.printStackTrace();
    }

    if (!isBTReady) {
      showInfo("蓝牙不可用");
      //删除Gauge
      this.delete(1);
      return;
    }

    uuidSet = new UUID[2];

    //标志我们的响应服务的UUID集合
    uuidSet[0] = new UUID(0x0100);
   // uuidSet[0] =ECHO_SERVER_UUID;
    uuidSet[1] = ECHO_SERVER_UUID;

    try {
      discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
    }
    catch (BluetoothStateException e) {

    }

    try {
      //阻塞,由inquiryCompleted()回调方法唤醒
      wait();
    }
    catch (InterruptedException e1) {

      e1.printStackTrace();
    }
    if (devices.size() > 0) {
        RemoteDevice rd1 = (RemoteDevice) devices.elementAt(0);
            String name = "";
            try {
                name = rd1.getFriendlyName(true);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
      showInfo("设备搜索完毕,共找到" + devices.size() + "个设备,Name= " + name.toString() + " 开始搜索服务");
     }
    else {
      showInfo("设备搜索完毕,共找到0个设备,不能提供服务。");
    }
    transIDs = new int[devices.size()];
    for (int i = 0; i < devices.size(); i++) {
      RemoteDevice rd = (RemoteDevice) devices.elementAt(i);
      try {
        //记录每一次服务搜索的事务id
        transIDs[i] = discoveryAgent.searchServices(attrSet, uuidSet,rd, this); //搜寻一个远程设备上的所有服务返回服务搜索的事务id
      }
      catch (BluetoothStateException e) {
        continue;
      }

    }

    try {
      //阻塞,由serviceSearchCompleted()回调方法在所有设备都搜索完的情况下唤醒
      wait();
    }
    catch (InterruptedException e1) {
      e1.printStackTrace();
    }
    if (records.size() > 0) {
       DataElement serviceNameElement = ((ServiceRecord)records.elementAt(0)).getAttributeValue(0x0100);//get the Service Name
        String serviceName = (String)serviceNameElement.getValue();

      showInfo("服务搜索完毕,共找到" + records.size() + "个服务,Name ="+serviceName.toString());
      //this.addCommand(new Command("开始说话", Command.OK, 3));

    }
    else {
      showInfo("服务搜索完毕,共找到" + records.size() + "个服务"+"/n"+"服务搜索完毕,没有找到服务。");
    }

    //删除Gauge
    this.delete(1);

  }
  public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {

    if (devices.indexOf(btDevice) == -1) {
      devices.addElement(btDevice);
    }
  }
  public void inquiryCompleted(int discType) {

    synchronized (this) {
      notify();
    }
  }
  public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
    for (int i = 0; i < servRecord.length; i++) {
      records.addElement(servRecord[i]);
    }
  }
  public void serviceSearchCompleted(int transID, int respCode) {

    for (int i = 0; i < transIDs.length; i++) {
      if (transIDs[i] == transID) {
        transIDs[i] = -1;
        break;
      }
    }

    //如果所有的设备都已经搜索服务完毕,则唤醒初始化线程。

    boolean finished = true;
    for (int i = 0; i < transIDs.length; i++) {
      if (transIDs[i] != -1) {
        finished = false;
        break;
      }
    }

    if (finished) {
      synchronized (this) {
        notify();
      }
    }

  }
}
class PrimeThread extends Thread {
     private java.io.DataOutputStream dos;
     private java.io.DataInputStream dis;
     ClientBox cbs;
     Player register;
      Player play;
      javax.microedition.media.control.RecordControl rc;
      StreamConnection conn ;
     PrimeThread(StreamConnection conn ,ClientBox c ) {
         this.conn = conn;
         cbs = c;
         }
     public void run() {
               try{
              
                    register = Manager.createPlayer("capture://audio");
                    register.realize();
                    rc = (javax.microedition.media.control.RecordControl)register.getControl("RecordControl");
                    dos = conn.openDataOutputStream();
                    rc.setRecordStream(dos);
                    cbs.input.setString("开始录音");
                    rc.startRecord();
                    register.start();
                    this.currentThread().sleep(3000);
                    rc.commit();
                    register.close();
                    cbs.input.setString("录音结束");
                    dos.close();
                    this.currentThread().sleep(1000);
                    dis = conn.openDataInputStream();
                    byte [] arry = new byte[44032];
                    cbs.input.setString("开始接收数据");
                    for( int i = 0;i<43;i++) {
                        if(i == 43) {
                            dis.read(arry,i*1024,44844-(1024*i));
                            cbs.input.setString("开始接收数据"+i);
                        }  else {
                           dis.read(arry,i*1024,1024);
                            cbs.input.setString("开始接收数据"+i);
                        }                
                   }
                    dis.close();
                    cbs.input.setString( cbs.input.getString()+"接收数据结束");
                    ByteArrayInputStream baInputs = new ByteArrayInputStream(arry);
                    play = Manager.createPlayer(baInputs, "audio/X-wav");
                    cbs.input.setString( cbs.input.getString()+"播放开始");
                    play.start();
                    this.currentThread().sleep(5000);
                    cbs.input.setString("播放结束");
                    play.close();
                   
               
               } catch (IOException ioe) {
                    cbs.input.setString(ioe.toString());
                    System.out.println(ioe.toString());
               } catch (MediaException me) {
                    cbs.input.setString(me.toString());
               } catch (InterruptedException ex) {
                    cbs.input.setString(ex.toString());
               }
         }
     public void distroy(){    
       try {
               if(rc != null){
                   rc.stopRecord();
                    rc.commit();
               }    
               if(register!=null){
                    register.stop();
               }
               if(play!=null) {
                  play.stop();
               }
               if( dos != null )
                   dos.close();
               if( dis != null )
                   dis.close();
               if( conn != null )
                    conn.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (MediaException ex) {
                ex.printStackTrace();
            }
       }
}

希望以上能够给解决初学者的困难,如果有不明白,可以给我留言。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值