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。