前言有老手私信,讲解蓝牙开发,所以今天就到这里;Android4.3(APILevel18)开始引入低功耗蓝牙(BLE,BluetoothLowEnergy)的核心功能并提供相应的API,应用程序通过这些API扫描蓝牙设备,查询服务,读写设备特性(attributecharacteristics)和其他操作。BLE低功耗蓝牙,主要特点是快速搜索,快速连接,超低功耗保持连接和数据传输;一、BLE开发流程1、Android手机申请权限,涉及到蓝牙权限。蓝牙开发需要在AndroidManifest.xml文件中添加权限声明:适用于Android6.0及以上版本需要添加模糊定位权限手机权限管理中允许该权限,否则该设备将无法被搜索到;适配Android6.0及以上版本需要在手机权限管理中添加模糊定位权限允许该权限,否则无法搜索到设备;2.打开蓝牙,搜索设备前要求打开手机蓝牙://获取系统蓝牙适配器管理类privateBluetoothAdaptermBluetoothAdapter=BluetoothAdapter.getDefaultAdapter();//要求打开蓝牙if(mBluetoothAdapter!=null&&!mBluetoothAdapter.isEnabled()){IntentenableBtIntent=newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);startActivityForResult(enableBtIntent,1);}//申请开启蓝牙请求回调@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){//TODOAuto-generatedmethodstubsuper.onActivityResult(请求代码、结果代码、数据);if(requestCode==1){if(resultCode==RESULT_OK){Toast.makeText(this,"蓝牙开启",Toast.LENGTH_SHORT).show();}elseif(resultCode==RESULT_CANCELED){Toast.makeText(this,"NoBluetoothpermission",Toast.LENGTH_SHORT).show();finish();}}}3.搜索设备mBluetoothAdapter.startLeScan(callback);privateLeScanCallbackcallback=newLeScanCallback(){@OverridepublicvoidonLeScan(BluetoothDevicedevice,intarg1,byte[]arg2){//device为扫描到的BLE设备if(device.getName()=="targetdevicename"){//获取目标设备targetDevice=device;}}};4.通过扫描BLEDevice连接设备,根据设备名称区分目标设备targetDevice,下一步实现与目标设备的连接,连接设备前停止搜索蓝牙;mBluetoothAdapter.stopLeScan(回调);停止搜索通常需要一定的时间,最好在调用stop函数后加上100ms的延迟,保证系统可以完全停止搜索蓝牙设备停止搜索后开始连接过程;BLE蓝牙连接方法比较简单,调用connectGatt方法即可;m蓝牙适配器。扫描到的BLE设备if(device.getName()==“目标设备名称”){//获取目标设备targetDevice=device;}}};参数说明返回值BluetoothGatt:BLE蓝牙连接管理类,主要负责与设备的连接通信;booleanautoConnect:建议设置为false,可以提高连接速度;BluetoothGattCallback回调连接回调,重要参数,BLE通信的核心部分;5.连接建立后设备通信和设备与设备通信,整个通信过程在BluetoothGattCallback的异常回复函数中完成;BluetoothGattCallback中主要回复函数如下:privateBluetoothGattCallbackgattCallback=newBluetoothGattCallback(){@OverridepublicvoidonConnectionStateChange(BluetoothGattg,intoothGattg,intnewState){}@OverridepublicvoidonCharacteristicWrite(BluetoothGattgatt,BluetoothGattCharacteristiccharacteristic,intstatus){super.onCharacteristicWrite(gatt,characteristic,status);}@OverridepublicvoidonDescriptorWrite(BluetoothGattgatt,BluetoothGattDescriptordescriptor,intstatus){};@Overridep公共voidonServicesDiscovered(BluetoothGattgatt、intstatus){}@OverridepublicvoidonCharacteristicChanged(BluetoothGattgatt、BluetoothGattCharacteristiccharacteristic){}};以上回调函数在BLE开发中必不可少;6.当设备连接成功后,调用targetdDevice.connectGatt(context,false,gattCallback)之后,系统会主动发起与BLE蓝牙设备的连接。如果连接成功,会回调onConnectionStateChange方法。处理过程如下:@OverridepublicvoidonConnectionStateChange(BluetoothGattgatt,intstatus,intnewState){if(newState==BluetoothGatt.STATE_CONNECTED){Log.e(TAG,"Startscanningservicewhenthedeviceisconnected");//开始扫描服务,Android蓝牙开发的重要步骤之一mBluetoothGatt.discoverServices();}if(newState==BluetoothGatt.STATE_DISCONNECTED){//连接断开/*连接断开后的相应处理*/}};判断newState==BluetoothGatt.STATE_CONNECTED表示此时设备连接成功;7.开启扫描服务mBluetoothGatt.discoverServices();扫描BLE设备服务是Android系统中关于BLE蓝牙开发的一个重要步骤,一般在设备连接成功后调用,扫描到设备服务后回调onServicesDiscovered()函数。函数原型如下:@OverridepublicvoidonServicesDiscovered(BluetoothGattgatt,intstatus){privateListservicesList;//获取服务列表servicesList=mBluetoothGatt.getServices();}BLE蓝牙协议下的数据通信方式主要采用三个类:BluetoothGattService、BluetoothGattCharacteristic和BluetoothGattDescriptor来实现通信;由多个BluetoothGattService组成;BluetoothGattCharacteristic是特征的简称,一个服务包含一个或多个特征,特征作为数据的基本单位;一个BluetoothGattCharacteristic特性包含一个数据值和关于特性的附加描述BluetoothGattDescriptor:一个用于描述特性的类,它也包含一个值;8.获取负责通信的BluetoothGattCharacteristic。BLE蓝牙开发主要由负责通信的BluetoothGattService完成,称为通信服务。通过硬件工程师提供的UUID获取通信服务。获取方法如下:BluetoothGattServiceservice=mBluetoothGatt.getService(UUID.fromString("蓝牙模块提供的用于通信的UUID字符串"));通信服务包括负责读写的BluetoothGattCharacteristic,分别称为notifyCharacteristic和writeCharacteristic。其中notifyCharacteristic负责开启监听,即启动接收数据的通道,writeCharacteristic负责写入数据;具体操作方法如下:BluetoothGattServiceservice=mBluetoothGatt.getService(UUID.fromString("蓝牙模块提供的通信服务的UUID字符串"));//例如形式如下:49535343-fe7d-4ae5-8fa9-9fafd205e455notifyCharacteristic=service.getCharacteristic(UUID.fromString("notifyuuid"));writeCharacteristic=service.getCharacteristic(UUID.fromString("writeuuid"));9.启用监控打开监控,即建立与设备通信的第一条数据通道。BLE开发中,只有在上位机开启监听成功后,才能与下位机收发数据。开启监听的方式如下:mBluetoothGatt.setCharacteristicNotification(notifyCharacteristic,true)BluetoothGattDescriptordescriptor=characteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));descriptor.setValue(BluetoothENGATT_DescriptorifNOmonitorisenabled如果成功,会回调BluetoothGattCallback中的onDescriptorWrite()方法,处理方法如下:@OverridepublicvoidonDescriptorWrite(BluetoothGattgatt,BluetoothGattDescriptordescriptor,intstatus){if(status==BluetoothGatt.GATT_SUCCESS){//监听是enable成功,命令可以写成设备Log.e(TAG,"Successfullyenablemonitoring");}};10.写入数据并监听成功后,通过向writeCharacteristic写入数据实现与下位机的通信。写法如下://value是上位机发给下位机的指令writeCharacteristic.setValue(value);mBluetoothGatt.writeCharacteristic(writeCharacteristic)其中:value一般为Hex格式的指令,其内容由蓝牙通信协议规定,用于设备通信;11、如果接收到的数据写入成功,会回调BluetoothGattCallback中的onCharacteristicWrite()方法,表示数据已经发送到下位机;@OverridepublicvoidonCharacteristicWrite(BluetoothGattgatt,BluetoothGattCharacteristiccharacteristic,intstatus){if(status==BluetoothGatt.GATT_SUCCESS){日志。e(TAG,"发送成功");}super.onCharacteristicWrite(gatt,characteristic,status);}如果发送的数据符合通信协议,下位机会回复相应的数据给上位机。通过回调onCharacteristicChanged()方法获取发送的数据,处理方式如下:@OverridepublicvoidonCharacteristicChanged(BluetoothGattgatt,BluetoothGattCharacteristiccharacteristic){//value为设备发送的数据,根据数据协议解析byte[]value=characteristic.getValue();}通过向下位机发送指令获取下位机的回复数据,即可完成与设备的通信过程;12.断开与设备的通讯完成后,必须断开与设备的连接。调用以下方法断开与设备的连接:mBluetoothGatt.disconnect();mBluetoothGatt.close();2、蓝牙操作注意事项蓝牙的读写操作必须串行化。写入数据和读取数据不能同时进行。如果调用写入数据的方法,则立即调用写入数据或读取数据的方法,第二次调用的方法将立即返回false,即当前无法执行该操作;Android连接周边设备数量有限。当不需要连接蓝牙设备时,必须调用BluetoothGatt#close方法释放资源;BluetoothAPI连接蓝牙设备的超时时间约为20s,具体时间取决于系统实现。有时有些设备连接蓝牙需要很长时间,大约十几秒。如果在某些设备上手动设置连接超时,可能会导致接下来的几次连接尝试返回state==133inBluetoothGattCallback#onConnectionStateChange;所有的蓝牙操作都使用Handler将操作固定在一个线程中,可以省去很多线程不同步带来的麻烦;综上所述,蓝牙开发存在很多问题。把问题静下心来分析,肯定能解决的。我们一起工作吧;