Android学习Android知识Android技术知识

蓝牙BLE

2017-02-04  本文已影响138人  倩shrimp

前提说明:
去年有个项目是关于通过手机控制平衡车(小车)来实现加速、锁车等一系列操作,其实就是通过蓝牙来控制的,项目做了很长时间了,一直想把有关蓝牙的这个模块自己记录下来方便自己查看,也算知识的一个积累吧。
自己第一次接触蓝牙开发的项目,对蓝牙这块不太熟悉,然后经过一番搜索找到的都是以下的蓝牙开发,自己也开始做起来,以为很简单,直接上代码了。

步骤(不支持BLE):
1、搜索蓝牙设备;
<pre>
// 1、获取系统的蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// 2、搜索蓝牙设备(搜索过程中会发出广播,可以注册广播,从广播中搜索到我们需要的设备)
bluetoothAdapter.startDiscovery();
</pre>

简单说明:

2、获取设备、配对、连接;
<pre>
// 3、注册系统广播,得到我们需要的设备
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BluetoothReceiver();
registerReceiver(receiver, filter);

// 广播
private class BluetoothReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (isLock(device)) {
devices.add(device.getName());
}
deviceList.add(device);
}
showDevices();
}
}
// 4、获取设备,并配对(只有配对好之后才能连接)
// 在连接设备之前停掉搜索设备,否则连接可能会变得非常慢并且容易失败
bluetoothAdapter.cancelDiscovery();</pre>
3、连接后获取输入输出流和蓝牙设备进行通信;
4、断开连接、关闭蓝牙;
<pre>
这两个步骤不说明,因为到这里我就发现问题了,
开发文档上说明找到uuid,在通道上发送和接收命令,
我却连个通道都没有见到过,找了很久都是以上这样的文章,
后来再从头阅读文档,发现了蓝牙BLE
呵呵~,懵逼了吧,再重新去搜索,又是另一番景象了。
</pre>

蓝牙BLE介绍(摘抄)

蓝牙BLE相关API:

步骤
1、开启手机蓝牙、搜索设备、取消搜索设备和以上相同;
2、蓝牙连接,发现服务、读写数据全部在回调里可以监听到:
<pre>
mBluetoothGatt = device.connectGatt(context, false, mGattCallback);

// 回调
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
final String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED)
{
intentAction = ACTION_GATT_CONNECTED;
// 开启查找服务
mBluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
// 断开连接
// Log.d(TAG, "Disconnected from GATT server.");
intentAction = ACTION_GATT_DISCONNECTED;
}
if (status == 133) { // 蓝牙连接自动断开的原因->需要清除所有的连接,重连机制
// Log.e(TAG, "蓝牙连接自动断开,status=" + status);
close();
sleep();
connect(mBluetoothDeviceAddress);
}
}

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {

// Log.d(TAG, "onServicesDiscovered received: " + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// 解析服务
displayGattServices(getSupportedGattServices());
}
}

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
                                     BluetoothGattCharacteristic characteristic,
                                     int status) {
    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
    }

    @Override public void onCharacteristicWrite(BluetoothGatt gatt,
        BluetoothGattCharacteristic characteristic, int status) {
    }
};

</pre>

解析服务,因为我是在FFE0、FFE5通道上操作的,所以只需要找到这两个通道即可:
<pre>
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) {
return;
}
for (BluetoothGattService gattService : gattServices) {
//-----Service的字段信息-----//
// Log.e(TAG,"-->service uuid:"+gattService.getUuid());

        String serviceUUID = gattService.getUuid().toString().toUpperCase();
        if (serviceUUID.contains(DefaultConstant.SERVICE_UUID_FFE0))
        {
            List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
            for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {

// Log.e(TAG, "---->char uuid:" + gattCharacteristic.getUuid());
String charUUID = gattCharacteristic.getUuid().toString().toUpperCase();
if (charUUID.contains(DefaultConstant.CHAR_UUID_FFE4)) {
mCharacFFE4 = gattCharacteristic;
// 打开通道,只有打开了通道,才能在通道上进行读和写
mBluetoothGatt.setCharacteristicNotification(gattCharacteristic, true);
break;
}
}
}
if (serviceUUID.contains(DefaultConstant.SERVICE_UUID_FFE5))
{
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
for (final BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
// Log.e(TAG, "---->char uuid:" + gattCharacteristic.getUuid());
String charUUID = gattCharacteristic.getUuid().toString().toUpperCase();
if (charUUID.contains(DefaultConstant.CHAR_UUID_FFE9)) {
mCharacFFE9 = gattCharacteristic;
break;
}
}
}
if (mCharacFFE4 != null && mCharacFFE9 != null) {
break;
}
}

}

</pre>

实际的值如下所示:


实际打印的服务和特征值.png

3、读写完成后记得关闭连接;

总结:最后总算顺利的完成了项目的开发,但是也还是遇到了很多的问题,这里自己做下记录:

好不容易鼓起自己去写了,一定会再接再励,代码自己会抽时间把之前写在项目中的代码抽离出来写个demo放github上去,知识需要沉淀。

添加github demo地址,写的较简单,后续逐渐完善https://github.com/ywqian/BluetoothDemo

参考和好的链接文章:
http://www.pinnace.cn/bluetooth/tech/1940.shtml
http://www.cnblogs.com/savagemorgan/p/3722657.html
一个不错的github列子:https://github.com/alt236/Bluetooth-LE-Library---Android

上一篇下一篇

猜你喜欢

热点阅读