四、程序设计
4.1 设置蓝牙权限
在AndroidManifast.xml配置文件中设置蓝牙操作权限。代码如下: android:name=\ 4.2 启动蓝牙功能 首先通过调用静态方法getDefaultAdapter()获取蓝牙适配器BluetoothAdapter,如果返回为空,说明该设备没有蓝牙适配器。代码如下: BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (mBluetoothAdapter == null) { } 其次,调用isEnabled()来查询当前蓝牙设备的状态,如果返回为false,则表示蓝牙设备没有开启,接下来你需要封装一个ACTION_REQUEST_ENABLE请求到intent里面,调用startActivityForResult()方法开启蓝牙设备。代码如下: if (!mBluetoothAdapter.isEnabled()) { Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION _REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } 4.3 设置蓝牙可见 设置蓝牙设备可见,使其他设备可以搜索到本机蓝牙设备,然后将ACTION_REQUEST_DISCOVERABLE动作封装在Intent中然后通过调用方法startActivity(Intent)可以实现在应用程序不退出的情况下使你的设备能够被发现。缺省情况下的使能时间是120秒,可以通过添加EXTRA_DISCOVERABLE_DURATION字段来改变使能时间(最大不超过300秒,这是出于对你设备上的信息安全考虑)。代码如下: Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); startActivity(discoverableIntent); 4.4 查询已配对蓝牙设备 在建立连接之前必须先查询已配对的蓝牙设备列表(你周围的蓝牙设备可能不止一个),以便你选取某一个设备进行数据通信。代码如下: Set if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { mArrayAdapter.add(device.getName() + \+ device.getAddress()); // 添加设备名和MAC地址到设备列表中 } 4.5 扫描周围蓝牙设备 BluetoothAdapter调用startDiscovery()方法异步扫描周围蓝牙设备,这个扫描的过程大概持续12秒,每扫描到一个BluetoothDevice系统就会广播ACTION_FOUND动作。BluetoothAdapter会注册一个BroadcastReceiver来获取该设备富的设备名和MAC地址。代码如下: private final BroadcastReceiver mReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)){ BluetoothDevice device = intent.getParcelableExtra(Bl uetoothDevice.EXTRA_DEVICE); stView mArrayAdapter.add(device.getName() + \+ device.getAddress()); } } }; IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); registerReceiver(mReceiver, filter); 4.6 服务器端的连接 首先用listenUsingRfcommWithServiceRecord(String, UUID)方法来获取BluetoothServerSocket对象,参数String代表了该服务的名称,UUID代表了和客户端连接的一个标识(128位格式的字符串ID,相当于PIN码),UUID必须双方匹配才可以建立连接。其次调用accept()方法来监听可能到来的连接请求,当监听到一个请求后,返回一个连接上的蓝牙套接字BluetoothSocket。最后,在接受到一个连接以后,调用close()方法来关闭监听程序,因为一般蓝牙设备之间是点对点的传输的。 注意:accept()方法不应该放在主Acitvity里面,因为它是一种阻塞调用,在没有监听到连接请求之前程序就一直停在那里,应该新建一个AcceptThread线程来管理。代码如下: private class AcceptThread extends Thread { private final BluetoothServerSocket mmServerSocket; public AcceptThread() { BluetoothServerSocket tmp = null; try { tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME , MY_UUID); } catch (IOException e) { } mmServerSocket = tmp; } public void run() { BluetoothSocket socket = null; while (true) { try { socket = mmServerSocket.accept(); } catch (IOException e) { break; } if (socket != null) { manageConnectedSocket(socket); mmServerSocket.close(); break; } } } public void cancel() { try { mmServerSocket.close(); } catch (IOException e) { } } } 4.7 客户端的连接 通过调用BluetoothDevice的createRfcommSocketToServiceRecord(UUID)方法来获取BluetoothSocket。UUID就是匹配码。然后调用connect()方法来请求数据连接。如果服务器端接受了该连接,他们将在通信过程中共享RFFCOMM信道。 注意:conncet()方法也是阻塞调用,一般建立一个独立的ConnectThread线程来调用该方法。在设备搜索过程中不应该发起连接connect()方法,这样会明显减慢速度以至于连接失败。且数据传输完成只有调用close()方法来关闭连接,这样可以节省系统内部资源。代码如下: private class ConnectThread extends Thread { private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device) { BluetoothSocket tmp = null; mmDevice = device; try { tmp = device.createRfcommSocketToServiceRecord(MY_UUI; } catch (IOException e) { } mmSocket = tmp; } public void run() { mAdapter.cancelDiscovery(); try { mmSocket.connect(); } catch (IOException connectException) { try { mmSocket.close(); } catch (IOException closeException) { } return; } manageConnectedSocket(mmSocket); } 4.8 数据通信线程 当两台设备连接上以后,每个设备都拥有各自的BluetoothSocket。现在就可以实现设备之间的数据通信了。首先通过调用getInputStream()和getOutputStream()方法来获取输入输出流。然后通过调用read(byte[]) 和write(byte[])方法来读取或者写数据。 注意:读取和写操作都是阻塞调用,需要建立一个单独的线程ConnectedThread来管理。 private class ConnectedThread extends Thread { private final BluetoothSocket mmSocket; private final InputStream mmInStream; private final OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) { mmSocket = socket; InputStream tmpIn = null;