开始前先看一下大致的流程
1、创建BluetoothServerSocket
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(
bluetoothAdapter.getName(),java.util.UUID.fromString(SPP_UUID));
通过listenUsingRfcommWithServiceRecord返回一个BluetoothServerSocket,参数为本地的蓝牙名称和uuid,uuid可以定制,客户端和服务端要使用同一个uuid才能建立起连接。从方法名上看出,这一步和RFCOMM建立了联系,另外还有一个相似的方法为listenUsingInsecureRfcommWithServiceRecord,区别为后者为不安全的。
2、等待连接
socket = serverSocket.accept();
BluetoothServerSocket服务端要保持开启等待接收客户端的连接。这一步是阻塞的,所以需要另外开启一个线程处理,这里所有涉及的子线程都通过线程池管理。通过BluetoothServerSocket的accept方法就能获取得到BluetoothSocket,通过BluetoothSocket就能获取客户端的一些信息和通信了。
3、读写数据
if(socket != null) {
serverInputStream = socket.getInputStream();
serverOutputStream = socket.getOutputStream();
//读取
readFromClient();
}
拿到BluetoothSocket之后就可以获取输入输出流进行通信了,接下来就是流的操作了。流操作也开启子线程处理,readFromClient()方法我简单封装了一下从客户端读取数据:
/**
* 从客户端读取数据
*/
private void readFormClient(){
fixedThreadPool.execute(new ReadTask(serverInputStream));
}
/**
* 读任务
*/
private class ReadTask implements Runnable{
InputStream inputStream;
public ReadTask(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
byte buffer[] = new byte[1024];
int bytes;
try {
while (true){
if((bytes= inputStream.read(buffer))!=0){
byte[] buf_data = new byte[bytes];
for (int i = 0; i < bytes; i++){
buf_data[i]=buffer[i];
}
Log.i(TAG, "接受数据: " + ByteUtil.byteArrToHex(buf_data));
BluetoothMsg msg = new BluetoothMsg(buf_data);
EventBus.getDefault().post(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalThreadStateException ww){
ww.printStackTrace();
}
}
}
写的操作也类似:
/**
* 写任务
*/
private class WriteTask implements Runnable {
byte[] writeBytes;
OutputStream outputStream;
public WriteTask(OutputStream outputStream, byte[] writeBytes){
this.outputStream = outputStream;
this.writeBytes = writeBytes;
}
@Override
public void run() {
if(outputStream != null){
try {
outputStream.write(writeBytes);
Log.i(TAG, "OutputStream: "+ByteUtil.byteArrToHex(writeBytes));
} catch (IOException e) {
e.printStackTrace();
}
}else{
Log.i(TAG, "OutputStream null");
}
}
}