最近作相关蓝牙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();
}
}
}
希望以上能够给解决初学者的困难,如果有不明白,可以给我留言。