当前位置:   article > 正文

Android——BLE通讯开发_android ble开发 是否需要service

android ble开发 是否需要service

最近穿戴设备发展得很火,我们公司也正在做健康类的穿戴设备,因此有机会研究了一把BLE(Bluetooth Low Energy)技术。
关于BLE技术的简介以及基本定义,本文就不再累述,各位看管可自行搜索查阅相关文档博客,本文只简述我个人对BLE开发过程的理解。

首先,关于BLE的通讯,是需要绑定在一个服务service上进行通讯的。因为BLE不像蓝牙2.0时代那样,维持一个长连接的BluetoothSocket,直接在这个Socket中通讯,通讯完成,关闭相关的Socket即可。而BLE之所以定义为低功耗的蓝牙,是因为它的通讯是每次有数据传输时才建立连接,传输完成连接就中断,因此才能做到低功耗。所以关于BLE的开发,才经常以开启一个service的形式来进行通讯。

// 将操作BLE的界面与服务绑定
mContext.bindService(new Intent(mContext,BluetoothLeService.class),mServiceConnection,Context.BIND_AUTO_CREATE);

// 服务绑定结果
private final ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
        // 处理服务绑定成功后的操作
            mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            isBound = true;
            mHandler.sendEmptyMessage(ConstValue.DEVICE_SCAN_BIND_SERVICE);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        // 处理服务绑定结束后的操作
        }
    };

// 为了接收BLE的回调,注册广播接收器
mContext.registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

绑定了操作界面和BLE服务之后,就需要连接BLE设备了

// 通过BLE的蓝牙MAC地址进行连接
public boolean connect(final String address) {
        if (mBluetoothAdapter == null || address == null) {
            Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
            return false;
        }

        if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) {
            if (mBluetoothGatt.connect()) {
                return true;
            } else {
                return false;
            }
        }

        final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) {
            Log.w(TAG, "Device not found.  Unable to connect.");
            return false;
        }
        mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
        mBluetoothDeviceAddress = address;
        return true;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

其中,device.connectGatt(this, false, mGattCallback)的参数中,需要添加BLE的回调

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {

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

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            broadcastUpdate(characteristic);
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            broadcastUpdate(characteristic);
        }

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

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            Log.d("ble", "stefano105onReadRemoteRssi");
            broadcastUpdate(characteristic);
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            broadcastUpdate(characteristic);
        };

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            Log.d("ble", "stefano107onCharacteristicChanged");
            broadcastUpdate(characteristic);
        }
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

关于上面的回调,很多大神也都有介绍使用方法(我觉得到了这个底部,BLE开发的公共部分该有的都有了,其他的就是依照不同的项目需求,来处理BLE的回调了)

最后,重点说明下开发过程中遇到的问题,以及个人理解和解决办法

* 设置多个Notify类型的特征值时,连续设置,会导致有些特征值并没有设置成功*

关于这个问题的详细技术原因,我也忘记了。。(主要是很久之前看到的,懒得再找了。。)反正大意就是,Android中的BLE设置命令并不是同步执行的,即不是执行完一个命令,再执行下一个命令。因为BLE执行设置命令是需要耗时的,所以如果连续的对BLE进行多个命令设置,会存在之前的命令还没有执行完,就被后一个命令覆盖,就导致上面的问题。

解决办法:因为设置命令,是需要write的,所以一个命令设置成功后,会回调以下函数

@Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {};
  • 1
  • 2

所以,对于需要连续设置多个命令的时候(如设置多个Notify类型的特征),虽然BLE无法将命令同步执行,但我们可以将设置命令先在本地代码中进行缓存,同步处理,如下

/**
    ***************************************************
     * @ 功能描述: 设置多个监听特征值的方法  
     */
    public void setCharacteristicNotifications(Queue<BluetoothGattCharacteristic> characteristics, boolean enabled) {
        if (mBluetoothAdapter == null || mBluetoothGatt == null) {
            Log.w(TAG, "BluetoothAdapter not initialized");
            return;
        }
        characteristicNotifyQueue = characteristics;
        setCharacteristicNotification(characteristicNotifyQueue.element(), enabled);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当onDescriptorWrite回调成功时,再执行下一个命令的设置,直到所有的命令设置完成

if (status == BluetoothGatt.GATT_SUCCESS) {
                characteristicNotifyQueue.remove();
                if (characteristicNotifyQueue.size() > 0) {
                    setCharacteristicNotification(characteristicNotifyQueue.element(), true);
                } else {
                    characteristicNotifyQueue.clear();
                    broadcastUpdate(UuidAndBroadcastFilter.ACTION_GATT_NOTIFYCATION_SETTED);
                }
            } else {
                if (characteristicNotifyQueue.size() > 0) {
                    setCharacteristicNotification(characteristicNotifyQueue.element(), true);
                }
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这样,就解决这个问题!

以上是个人对于BLE开发的理解,不喜勿喷!!! 转载请说明出处~谢谢~~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/573733
推荐阅读
相关标签
  

闽ICP备14008679号