1、检查设备是否支持蓝牙设备:
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this,"不支持BLE功能",Toast.LENGTH_SHORT).show(); finish(); } else { Toast.makeText(this,"支持BLE功能",Toast.LENGTH_SHORT).show(); }
2、获取本机的蓝牙适配器:
mBleAdapter = BluetoothAdapter.getDefaultAdapter();
3、打开蓝牙设备:
if(mBleAdapter != null || !mBleAdapter.isEnable())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
or
mBleAdapter .enable(); //打开;
mBleAdapter .disable(); //关闭;
4、注册事件的广播并开始扫描周末设备:
//开始扫描设备 public void startDiscoveryDevice() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); blueContext.registerReceiver(blueEventRecv, filter); //注册要接收的广播消息 if(bluetoothAdapter.isDiscovering() == false) bluetoothAdapter.startDiscovery() } //停止扫描设备 public void stopDiscoveryDevice() { if(bluetoothAdapter.isDiscovering() ) bluetoothAdapter.cancelDiscovery(); }
5、配对以及连接周边蓝牙设备: 4.0和2.0的区别在此处4.0的直接连接,4.0似乎不需要进行配对。
首先声明一个回调,供GATT上各种事件产生变化时调用:
private BluetoothGattCallback bluetoothGattCallBack= new BluetoothGattCallback() {
@Override
public voidonConnectionStateChange(BluetoothGatt gatt,int status, intnewState) {
super.onConnectionStateChange(gatt, status, newState);
if(newState == BluetoothGatt.STATE_CONNECTED) {
Log.d(TAG,"onConnectionStateChange: 连接成功 ->"+bluetoothGatt.discoverServices());
}
}
@Override
public voidonServicesDiscovered(BluetoothGatt gatt, intstatus) {
super.onServicesDiscovered(gatt, status);
if(status == BluetoothGatt.GATT_SUCCESS){
List<BluetoothGattService> services = bluetoothGatt.getServices();
Log.d(TAG,"onServicesDiscovered: 共有"+ services.size());
for(inti=0;i< services.size();i++) {
Log.e(TAG,"onServicesDiscovered: 服务 UUID =" + services.get(i).getUuid() );
List<BluetoothGattCharacteristic> listGattChar = services.get(i).getCharacteristics();
for(intj=0; j < listGattChar.size(); j++){
Log.e(TAG,"onServicesDiscovered: --特征 UUID="+listGattChar.get(j).getUuid() );
}
}
BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(HC_UUID_SERV));
if(service !=null) {
bluetoothCharacter = service.getCharacteristic(UUID.fromString(HC_UUID_CHAR));
bluetoothGatt.readCharacteristic(bluetoothCharacter);
Log.e(TAG,"onServicesDiscovered: 获取特征值成功" );
}
else
Log.e(TAG,"onServicesDiscovered: 获取特征值失败" );
}
else{
Log.e(TAG,"onServicesDiscovered: 收到事件状态"+ status );
}
}
@Override
public voidonCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
if(status == BluetoothGatt.GATT_SUCCESS){
Log.d(TAG,"onCharacteristicWrite: 写数据成功 ->"+new String(characteristic.getValue()));
}
else{
Log.d(TAG,"onCharacteristicWrite: 写数据失败"+ status);
}
}
@Override
public voidonCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
byte[] buffer = characteristic.getValue();
String string = new String(buffer);
Log.d(TAG,"onCharacteristicChanged: "+string);
callBackForState.onDataReceived(string);
}
@Override
public voidonCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if(status == BluetoothGatt.GATT_SUCCESS){
byte[] buffer = characteristic.getValue();
if(buffer.length> 1) {
String str = new String(buffer);
Log.d(TAG,"onCharacteristicRead: " + gatt.getDevice().getName()+":"+characteristic.getUuid().toString());
Log.d(TAG,"onCharacteristicRead: 读数据成功:" + str);
bluetoothGatt.readCharacteristic(bluetoothCharacter);
}
System.out.println(newString(buffer));
}
else{
Log.d(TAG,"onCharacteristicRead: 写数据失败:"+ status);
}
}
@Override
public voidonDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,int status) {
super.onDescriptorRead(gatt, descriptor, status);
byte[] desc = descriptor.getValue();
if (desc != null) {
Log.w(TAG,"----onDescriptorRead value: 读取描述 ->" + new String(desc));
}
}
};
然后配对蓝牙设备:由于是BLE所以要使用GATT。主要是使用connectGatt获得BluetoothGatt对象,然后通过BluetoothGatt对象连建立连接。
public void bondBlueDevice(BluetoothDevice device)
{
if (device != null) {
bluetoothGatt = device.connectGatt(blueContext,true,bluetoothGattCallBack);
bluetoothGatt.connect();
}
else{
Log.d(TAG,"bondBlueDevice: 配对失败,设备为空");
}
}
7、发送数据到远端设备
发送和接收都是使用蓝牙的Characteristic进行中转处理的即不是由特性直接进行发送的。而是将值设置进bluetoothCharacter中,在有bluetoothGatt将特性给发送出去。
public boolean sendTest()
{
if(bluetoothCharacter!= null){
bluetoothGatt.setCharacteristicNotification(bluetoothCharacter,true);
bluetoothCharacter.setValue("hello world".getBytes());
bluetoothCharacter.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
bluetoothGatt.writeCharacteristic(bluetoothCharacter);
return true;
}
else {
Log.d(TAG,"sendTest:blueCharacter为空");
return false;
}
}
8、接收远端蓝牙数据:
BLE的接收数据是在之前我们在配对时所注册进去的回调onCharacteristicChanged()中处理的,这里要加一句坑爹的函数名,一直以为是onCharacteristicRead中来处理所接收的数据的。为了这个折腾了很久。结果在一个博客中,无意看到了一句话(由BluetoothGattCallback的onCharacteristicChanged打印的数据),才恍然大悟。
public voidonCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
byte[] buffer = characteristic.getValue();
String string = new String(buffer);
Log.d(TAG,"onCharacteristicChanged: "+string);
callBackForState.onDataReceived(string);
}