📄 btclient.java
字号:
package com.j2medev.chapter8.bt;
import java.io.*;
import java.util.*;
import javax.bluetooth.*;
import javax.bluetooth.UUID;
import javax.microedition.io.*;
public class BTClient implements DiscoveryListener, Runnable {
public static final String uuidString = "0123456789ABCDEF0123456789ABCDEF";
public static UUID uuid;
private LocalDevice localDevice;// 本地设备实例
String localBTAddress;// 本地蓝牙地址
String localBTName;// 蓝牙名称
BTClientUI ui;
DiscoveryAgent discoveryAgent;// 发现代理
Thread th;
Thread readWorkTh;
Thread writeWorkTh;
StreamConnection conn;
boolean exitFlag;
boolean BTReady;//状态标记
DataInputStream in;
DataOutputStream out;
String sendText = "";
Hashtable remoteDevices = new Hashtable();// 存储找到的远程设备
String url = null;
ServiceRecord serviceRecord;
public BTClient(BTClientUI ui) {
this.ui = ui;
th = new Thread(this);
th.start();
}
public boolean initBT() {
boolean success = false;
try {
uuid = new UUID(uuidString, false);// 我们的UUID
// 取得本地设备实例
localDevice = LocalDevice.getLocalDevice();
// 记录蓝牙地址
localBTAddress = localDevice.getBluetoothAddress();
// 记录蓝牙名称
localBTName = localDevice.getFriendlyName();
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
// 取得蓝牙代理
discoveryAgent = localDevice.getDiscoveryAgent();
success = true;
} catch (Exception e) {
System.err.println("初始化蓝牙设备失败:" + e);
}
return success;
}
public void search() {// 搜索设备,搜索服务
try {
// 清除remoteDevices
remoteDevices.clear();
// 将缓存的和已知的蓝牙设备加入remoteDevices
RemoteDevice[] cacheDevices = discoveryAgent
.retrieveDevices(DiscoveryAgent.CACHED);
if (cacheDevices != null) {
for (int i = 0; i < cacheDevices.length; i++) {
remoteDevices.put(cacheDevices[i].getBluetoothAddress(),
cacheDevices[i]);
}
}
RemoteDevice[] preDevices = discoveryAgent
.retrieveDevices(DiscoveryAgent.PREKNOWN);
if (preDevices != null) {
for (int i = 0; i < preDevices.length; i++) {
remoteDevices.put(cacheDevices[i].getBluetoothAddress(),
cacheDevices[i]);
}
}
// 在已知的设备上查询服务
searchServices(remoteDevices);
if (serviceRecord != null)// 找到返回
return;
// 开始搜索设备
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);
// 在搜索到的设备上查询服务
// searchServices(remoteDevices);
// remoteDevices.clear();
} catch (BluetoothStateException e) {
e.printStackTrace();
}
if (serviceRecord != null) {
notify();
} else {
ui.state.setText("未发现设备或服务");
}
}
private void searchServices(Hashtable remotes)
throws BluetoothStateException {// 搜索服务
// 创建我们感兴趣的UUID数组
UUID[] UUIDs = new UUID[2];
UUIDs[1] = new UUID(uuidString, false);// 我们的UUID
UUIDs[0] = new UUID(0x0003);// 必须支持RFCOMM
// 取出每一个设备查询
for (Enumeration e = remotes.keys(); e.hasMoreElements();) {
String key = (String) e.nextElement();
RemoteDevice remoteDevice = (RemoteDevice) remotes.get(key);
// 查询
discoveryAgent.searchServices(null, UUIDs, remoteDevice, this);
}
}
public void deviceDiscovered(RemoteDevice device, DeviceClass cod) {
// 记录找到的设备
remoteDevices.put(device.getBluetoothAddress(), device);
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
// 发现感兴趣的服务,这里直接使用第一个
if (servRecord == null || servRecord.length == 0) {
url = null;
serviceRecord = null;
return;
}
// 取得感兴趣的连接URL
serviceRecord = servRecord[0];
url = serviceRecord.getConnectionURL(
ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
}
public void serviceSearchCompleted(int transID, int respCode) {
synchronized (this) {
notifyAll();
}
}
public void inquiryCompleted(int discType) {
try {
searchServices(remoteDevices);
} catch (BluetoothStateException e) {
e.printStackTrace();
}
remoteDevices.clear();
}
public void run() {
if (!initBT()) {
ui.state.setText("初始化失败");
return;
}
try {
ui.state.setText("开始查找");
// 等待启动服务搜索
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (exitFlag)
return;
search();
// 等待URL准备好
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (exitFlag)
return;
conn = (StreamConnection) Connector.open(url);
in = conn.openDataInputStream();
out = conn.openDataOutputStream();
readWorkTh = new ReadWorkThread();
readWorkTh.start();
writeWorkTh = new WriteWorkThread();
writeWorkTh.start();
ui.state.setText("准备就绪");
BTReady = true;
} catch (IOException e) {
ui.state.setText("初始化失败");
return;
} catch (SecurityException e) {
ui.state.setText("初始化失败");
return;
}
th = null;
}
public void close() {
try {
exitFlag = true;
synchronized (this) {
notify();
}
if (writeWorkTh != null) {
synchronized (writeWorkTh) {
writeWorkTh.notify();
}
}
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
if (conn != null)
conn.close();
if (readWorkTh != null) {
readWorkTh.join();
}
if (writeWorkTh != null)
writeWorkTh.join();
if (th != null)
th.join();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void send(String str) {
if (writeWorkTh == null)
return;
sendText = str;
synchronized (writeWorkTh) {
writeWorkTh.notify();
}
}
class ReadWorkThread extends Thread {
public void run() {
try {
while (!exitFlag) {
String str = in.readUTF();
if (str != null) {
ui.receiveTF.setString(str);
}
}
} catch (IOException e) {
if (!exitFlag)
ui.state.setText("读取数据失败");
}
}
}
class WriteWorkThread extends Thread {
public void run() {
try {
while (!exitFlag) {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
if (exitFlag)// 可能因为关闭操作被打断
break;
if (sendText != null)
out.writeUTF(sendText);
}
}
} catch (IOException e) {
if (!exitFlag)
ui.state.setText("写书据失败");
}
}
}
public void startSearch() {
synchronized (this) {
notifyAll();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -