10.2.2 基于蓝牙的通信
实现基于蓝牙的通信,需要完成两件事情:首先是扫描周边的蓝牙设备,与目标设备进行配对(Pair);其次与目标设备建立蓝牙通信连接,并实现数据传输。
由于蓝牙设备的信号传输距离约有10米左右,在此半径的圆周覆盖范围内,可能存在多个相关的蓝牙设备,系统需要在用户的帮助下找到目标设备,并进行配对,而后才能开始传输数据。在Android中,使用android.bluetooth.BluetoothAdapter对象管理和连接蓝牙设备。调用Bluetooth.startDiscovery函数可以开始扫描并尝试发现周边的蓝牙设备,当有新的蓝牙设备被发现时,系统会发出相应的广播事件,将寻找到的蓝牙设备的事件通知给监听者:
…
BroadcastReceiver bluetoothReceiver=BroadcastReceiver(){
void onReceive(Context context, Intent intent){
//从广播事件中,获取新的设备信息
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device=intent.getParcelableExtra(
BluetoothDevice.EXTRA_DEVICE);
…//将设备添加到列表中
}
}
};
protected void onResume(){
//开始扫描,并监听结果
BluetoothAdapter.getDefault().startDiscovery();
registerReceiver(bluetoothReceiver, new IntentFilter(
BluetoothDevice.ACTION_FOUND));
super.onResume();
}
protected void onPause(){
//取消扫描,并停止监听,也可放入onDestroy函数中
BluetoothAdapter.getDefault().cancelDiscovery();
unregisterReceiver(bluetoothReceiver);
super.onPause();
}
广播事件的附加域BluetoothDevice.EXTRA_DEVICE中,存储了二进制的设备信息,监听者可以解析该数据得到新设备的android.bluetooth.BluetoothDevice对象。
找到需要连接的设备后,蓝牙设备就可以与该设备配对并通信。基于蓝牙的通信,与普通的Socket连接类似,一个设备作为服务端监听端口等待请求,另一个设备作为客户端连接端口发起请求。通过BluetoothDevice.createRfcommSocketToServiceRecord函数可以发起连接:
//向给定的蓝牙设备发起连接请求
BluetoothSocket client=aBluetoothDevice
.createRfcommSocketToServiceRecord(MY_UUID);
…
//通常会在单独的线程中,建立通信连接并传输数据
client.connect();
writeData(client.getInputStream());
client.close();
其中,android.bluetooth.BluetoothSocket对象用来表示作为客户端进行连接的蓝牙Socket对象。而android.bluetooth.BluetoothServerSocket对象表示作为服务端等待连接的蓝牙Socket对象,其建立流程与客户端类似[1]:
//开始监听,等待连接
BluetoothServerSocket server=BluetoothAdapter.getDefault()
.listenUsingRfcommWithServiceRecord(MY_NAME, MY_UUID);
…
//通常会在独立的线程中,尝试与连接它的客户端建立连接,并开始传输数据
BluetoothSocket connection=server.accept();
If(connection!=null){
readData(connection.getOutputStream());
connection.close();
}
…
server.close();
[1]更多关于Android蓝牙开发的示例和介绍,可以参看SDK。