前言
公司有个项目,是使用Android设备和嵌入式设备之间进行通讯,且通讯方式采用的是蓝牙连接的方式,蓝牙通讯相当于串口通讯,传输的都是字节流,所以需要自己设定通信协议,规定字节编解码的方法。本文主要说的是Android平台的蓝牙API使用方法。参考了百度上的文章,并且指出自己在使用Android蓝牙接口过程中遇到的困难。
使用
蓝牙编程和socket编程步骤很像。需要注意的是:
* 服务端的Accept和客户端的connect操作都是阻塞的,所以需要在单开一个线程去操作,且两端的读写操作也都是阻塞的,也需要在独立的线程去操作。
* 必须使用Android的SSP(协议栈默认)的UUID:
**00001101-0000-1000-8000-00805F9B34FB
**
才能正常和外部的,也是SSP串口的蓝牙设备去连接。
客户端主要函数(我是手动配对,然后连接的)
public class BluetoothClient extends Thread
{
public BluetoothClient(ICallback callback) {
super(callback);
}
private BluetoothSocket mSocket;
private BluetoothAdapter mAdapter;
private BluetoothDevice mTargetServerDevice;
protected InputStream mInStream;
protected OutputStream mOutStream;
public void init() {
try{
mAdapter = BluetoothAdapter.getDefaultAdapter();
if (mAdapter == null){
mSocket = null;
return;// Device does not support Bluetooth
}
if (!mAdapter.isEnabled()) {
mAdapter.enable();
while(!mAdapter.isEnabled()){}
}
Set<BluetoothDevice> pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
// Use a temporary object that is later assigned to mmSocket, because mmSocket is final
if (device.getAddress().equals("00:04:3E:94:2C:FF"))
{
mTargetServerDevice = device;
}
}
}
mSocket = mTargetServerDevice.createRfcommSocketToServiceRecord
(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
}catch(Exception e){
throw new InitExecption(e);
}
}
public void run() {
if (mSocket == null){
return;
}
mAdapter.cancelDiscovery();
try
{
// Connect the device through the socket. This will block until it succeeds or throws an exception
mSocket.connect();
mInStream = mSocket.getInputStream();
mOutStream = mSocket.getOutputStream();
}
catch (IOException connectException)
{
if(mInStream != null){
try
{
mInStream.close();
}
catch (IOException closeException) {}
}
if(mOutStream != null){
try
{
mOutStream.close();
}
catch (IOException closeException) {}
}
if(mSocket != null){
try
{
mSocket.close();
}
catch (IOException closeException) {}
}
throw new ConnectException(connectException);
}
// Do work to manage the connection (in a separate thread)
}
}
服务端主要代码
public class BluetoothServer extends Thread
{
private final BluetoothServerSocket mServerSocket;
private ManageThread mDataManager;
public BluetoothServer()
{
// Use a temporary object that is later assigned to mmServerSocket,because mmServerSocket is final
BluetoothServerSocket tmp = null;
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord
("server", UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch (IOException e) { }
mServerSocket = tmp;
}
public void run() {
if (mServerSocket == null){
return;
}
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true)
{
try {
socket = mServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null)
{
//todo 对socket进行操作(读和写都应该在各自独立的线程)
break;
}
}
}
}