1. 使用蓝牙的响应权限

1 <strong> <uses-permissionandroid:name="android.permission.BLUETOOTH"/>
2 <uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/> </strong>


2. 配置本机蓝牙模块

在这里首先要了解对蓝牙操作一个核心类BluetoothAdapter

01 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
02 //直接打开系统的蓝牙设置面板
03 Intent intent =newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
04 startActivityForResult(intent,0x1);
05 //直接打开蓝牙
06 adapter.enable();
07 //关闭蓝牙
08 adapter.disable();
09 //打开本机的蓝牙发现功能(默认打开120秒,可以将时间最多延长至300秒)
10 discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,300);//设置持续时间(最多300秒)Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

3.搜索蓝牙设备

使用BluetoothAdapter的startDiscovery()方法来搜索蓝牙设备

startDiscovery()方法是一个异步方法,调用后会立即返回。该方法会进行对其他蓝牙设备的搜索,该过程会持续12秒。该方法调用后,搜索过程实际上是在一个System Service中进行的,所以可以调用cancelDiscovery()方法来停止搜索(该方法可以在未执行discovery请求时调用)。

请求Discovery后,系统开始搜索蓝牙设备,在这个过程中,系统会发送以下三个广播:

ACTION_DISCOVERY_START:开始搜索

ACTION_DISCOVERY_FINISHED:搜索结束

ACTION_FOUND:找到设备,这个Intent中包含两个extra fields:EXTRA_DEVICE和EXTRA_CLASS,分别包含BluetooDevice和BluetoothClass。

我们可以自己注册相应的BroadcastReceiver来接收响应的广播,以便实现某些功能

01 // 创建一个接收ACTION_FOUND广播的BroadcastReceiver
02 privatefinalBroadcastReceiver mReceiver =newBroadcastReceiver() {
03 publicvoidonReceive(Context context, Intent intent) {
04 String action = intent.getAction();
05 // 发现设备
06 if(BluetoothDevice.ACTION_FOUND.equals(action)) {
07 // 从Intent中获取设备对象
08 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
09 // 将设备名称和地址放入array adapter,以便在ListView中显示
10 mArrayAdapter.add(device.getName() +"\n"+ device.getAddress());
11 }
12 }
13 };
14 // 注册BroadcastReceiver
15 IntentFilter filter =newIntentFilter(BluetoothDevice.ACTION_FOUND);
16 registerReceiver(mReceiver, filter);// 不要忘了之后解除绑定

4. 蓝牙Socket通信

如果打算建议两个蓝牙设备之间的连接,则必须实现服务器端与客户端的机制。当两个设备在同一个RFCOMM channel下分别拥有一个连接的BluetoothSocket,这两个设备才可以说是建立了连接。

服务器设备与客户端设备获取BluetoothSocket的途径是不同的。服务器设备是通过accepted一个incoming connection来获取的,而客户端设备则是通过打开一个到服务器的RFCOMM channel来获取的。

服务器端的实现

通过调用BluetoothAdapter的listenUsingRfcommWithServiceRecord(String, UUID)方法来获取BluetoothServerSocket(UUID用于客户端与服务器端之间的配对)

调用BluetoothServerSocket的accept()方法监听连接请求,如果收到请求,则返回一个BluetoothSocket实例(此方法为block方法,应置于新线程中)

如果不想在accept其他的连接,则调用BluetoothServerSocket的close()方法释放资源(调用该方法后,之前获得的BluetoothSocket实例并没有close。但由于RFCOMM一个时刻只允许在一条channel中有一个连接,则一般在accept一个连接后,便close掉BluetoothServerSocket

01 privateclassAcceptThreadextendsThread {
02 privatefinalBluetoothServerSocket mmServerSocket;
03
04 publicAcceptThread() {
05 // Use a temporary object that is later assigned to mmServerSocket,
06 // because mmServerSocket is final
07 BluetoothServerSocket tmp =null;
08 try{
09 // MY_UUID is the app's UUID string, also used by the client code
10 tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
11 }catch(IOException e) { }
12 mmServerSocket = tmp;
13 }
14
15 publicvoidrun() {
16 BluetoothSocket socket =null;
17 // Keep listening until exception occurs or a socket is returned
18 while(true) {
19 try{
20 socket = mmServerSocket.accept();
21 }catch(IOException e) {
22 break;
23 }
24 // If a connection was accepted
25 if(socket !=null) {
26 // Do work to manage the connection (in a separate thread)
27 manageConnectedSocket(socket);
28 mmServerSocket.close();
29 break;
30 }
31 }
32 }
33
34 /** Will cancel the listening socket, and cause the thread to finish */
35 publicvoidcancel() {
36 try{
37 mmServerSocket.close();
38 }catch(IOException e) { }
39 }
40 }

客户端的实现

通过搜索得到服务器端的BluetoothService

调用BluetoothService的listenUsingRfcommWithServiceRecord(String, UUID)方法获取BluetoothSocket(该UUID应该同于服务器端的UUID)

调用BluetoothSocket的connect()方法(该方法为block方法),如果UUID同服务器端的UUID匹配,并且连接被服务器端accept,则connect()方法返回

注意:在调用connect()方法之前,应当确定当前没有搜索设备,否则连接会变得非常慢并且容易失败

01 <strong>privateclassConnectThreadextendsThread {
02 privatefinalBluetoothSocket mmSocket;
03 privatefinalBluetoothDevice mmDevice;
04
05 publicConnectThread(BluetoothDevice device) {
06 // Use a temporary object that is later assigned to mmSocket,
07 // because mmSocket is final
08 BluetoothSocket tmp =null;
09 mmDevice = device;
10
11 // Get a BluetoothSocket to connect with the given BluetoothDevice
12 try{
13 // MY_UUID is the app's UUID string, also used by the server code
14 tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
15 }catch(IOException e) { }
16 mmSocket = tmp;
17 }
18
19 publicvoidrun() {
20 // Cancel discovery because it will slow down the connection
21 mBluetoothAdapter.cancelDiscovery();
22
23 try{
24 // Connect the device through the socket. This will block
25 // until it succeeds or throws an exception
26 mmSocket.connect();
27 }catch(IOException connectException) {
28 // Unable to connect; close the socket and get out
29 try{
30 mmSocket.close();
31 }catch(IOException closeException) { }
32 return;
33 }
34
35 // Do work to manage the connection (in a separate thread)
36 manageConnectedSocket(mmSocket);
37 }
38
39 /** Will cancel an in-progress connection, and close the socket */
40 publicvoidcancel() {
41 try{
42 mmSocket.close();
43 }catch(IOException e) { }
44 }
45 } </strong>

连接管理(数据通信)

分别通过BluetoothSocket的getInputStream()和getOutputStream()方法获取InputStream和OutputStream

使用read(bytes[])和write(bytes[])方法分别进行读写操作

注意:read(bytes[])方法会一直block,知道从流中读取到信息,而write(bytes[])方法并不是经常的block(比如在另一设备没有及时read或者中间缓冲区已满的情况下,write方法会block)

01 <strong>privateclassConnectedThreadextendsThread {
02 privatefinalBluetoothSocket mmSocket;
03 privatefinalInputStream mmInStream;
04 privatefinalOutputStream mmOutStream;
05
06 publicConnectedThread(BluetoothSocket socket) {
07 mmSocket = socket;
08 InputStream tmpIn =null;
09 OutputStream tmpOut =null;
10
11 // Get the input and output streams, using temp objects because
12 // member streams are final
13 try{
14 tmpIn = socket.getInputStream();
15 tmpOut = socket.getOutputStream();
16 }catch(IOException e) { }
17
18 mmInStream = tmpIn;
19 mmOutStream = tmpOut;
20 }
21
22 publicvoidrun() {
23 byte[] buffer =newbyte[1024];// buffer store for the stream

更多相关文章

  1. Android(安卓)ProgressDialog 最佳处理方式
  2. Android(安卓)ProgressDialog 最佳处理方式
  3. Android:Galaxy Nexus升级到4.1.2,并root(设备是日版)
  4. Android(安卓)Ble
  5. Android系统属性SystemProperties.set/get详解
  6. Android(安卓)WebView中的JavaScript调用android方法
  7. Android(安卓)控件的显示和隐藏
  8. Android(安卓)Studio 快捷键
  9. android 中让activity全屏幕显示

随机推荐

  1. ubuntu ffmpeg 4.0.1 android 编译过程记
  2. Android常用查询网站
  3. Androidstudio 错误处理
  4. IT技术权威网站和深度博客
  5. Android中SQLiteDatabase的使用
  6. 《Android开发从零开始》——12.Relative
  7. android SAX parse xml
  8. android 判断网络并Wifi网络连接
  9. linux上cocos2dx Android打包环境
  10. Android Studio Mac版快捷键