美文网首页智能家居
android 低功耗蓝牙BLE多连接,多设备通信

android 低功耗蓝牙BLE多连接,多设备通信

作者: 玉树林枫 | 来源:发表于2017-04-11 19:27 被阅读1389次

    现在很多做蓝牙APP的都需要同时连接多个设备,那该怎么才能同时管理多个设备呢?以下是本人的方法,主要是通过ArrayMap来管理不同设备的BluetoothGatt,然后使用各自的BluetoothGatt来和从机进行数据交互,我们可以绑定该service进行方法的调用。

    public class BluetoothLeService2 extends Service {
    
    private ArrayMap<String, BluetoothGatt> gattArrayMap = new ArrayMap<>();
    private BluetoothAdapter mBluetoothAdapter;
    
    @Override
    public void onCreate() {
        super.onCreate();
        initBluetooth();
    }
    
    /**
     * 蓝牙是否开启
     */
    public boolean isBluetoothEnabled() {
        return mBluetoothAdapter.isEnabled();
    }
    
    
    private void initBluetooth() {
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
    }
    
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, Service.START_FLAG_RETRY, startId);
    }
    
    
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    
    
    public class LocalBinder extends Binder {
        public BluetoothLeService2 getService() {
            return BluetoothLeService2.this;
        }
    }
    
    private final IBinder mBinder = new LocalBinder();
    
    @Override
    public boolean onUnbind(Intent intent) {
        return super.onUnbind(intent);
    }
    
    
    /**
     * 连接设备
     *
     * @param address 设备地址
     */
    public synchronized void connect(final String address) {
        BluetoothGatt gatt = gattArrayMap.get(address);
        if (gatt != null) {
            gatt.disconnect();
            gatt.close();
            gattArrayMap.remove(address);
        }
        BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
        if (device == null) return;
        device.connectGatt(this, false, mGattCallback);
    }
    
    //蓝牙连接,数据通信的回掉
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
            String address = gatt.getDevice().getAddress();
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothGatt.STATE_CONNECTED) {// 连接成功
                    gatt.discoverServices();// 寻找服务
                    gattArrayMap.put(address, gatt);
                    Log.i("yushu", "connect succeed: ");
                } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {// 断开连接
                    onDisConnected(gatt, address);
                    Log.i("yushu", "connect fail ");
                }
            } else {
                onDisConnected(gatt, address);
                Log.i("yushu", "connect fail ");
            }
        }
    
    
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                enableNotification(gatt);//notification
            }
        }
    
    
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            byte[] value = characteristic.getValue();
    /**
     * 这里可以拿到设备notification回来的数据
    */
    
        }
    
    
        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
    
            }
        }
    };
    
    
    private void onDisConnected(BluetoothGatt gatt, String address) {
        gatt.disconnect();
        gatt.close();
    }
    
    
    /**
     * 使能通知
     */
    private void enableNotification(BluetoothGatt mBluetoothGatt) {
        if (mBluetoothGatt == null) return;
        BluetoothGattService ableService = mBluetoothGatt.getService(UUIDUtils.UUID_LOST_SERVICE);
        if (ableService == null) return;
        BluetoothGattCharacteristic TxPowerLevel = ableService.getCharacteristic(UUIDUtils.UUID_LOST_ENABLE);
        if (TxPowerLevel == null) return;
        setCharacteristicNotification(mBluetoothGatt, TxPowerLevel, true);
    }
    
    /**
     * 使能通知
     */
    private void setCharacteristicNotification(BluetoothGatt mBluetoothGatt, BluetoothGattCharacteristic characteristic, boolean enabled) {
        if (mBluetoothGatt == null) return;
        mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
        if (UUIDUtils.UUID_LOST_ENABLE.equals(characteristic.getUuid())) {
            BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUIDUtils.CLIENT_CHARACTERISTIC_CONFIG);
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBluetoothGatt.writeDescriptor(descriptor);
        }
    }
    
    
    /**
     * 写数据到硬件,这里的服务UUID和特这的UUID参考硬件那边,两边要对应
     */
    public synchronized void writeDataToDevice(byte[] bs, String address) {
        BluetoothGatt mBluetoothGatt = gattArrayMap.get(address);
        if (mBluetoothGatt == null) return;
        BluetoothGattService alertService = mBluetoothGatt.getService(UUIDUtils.UUID_LOST_SERVICE);
        if (alertService == null) return;
        BluetoothGattCharacteristic alertLevel = alertService.getCharacteristic(UUIDUtils.UUID_LOST_WRITE);
        if (alertLevel == null) return;
        alertLevel.setValue(bs);
        alertLevel.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
        mBluetoothGatt.writeCharacteristic(alertLevel);
    }
    
    
    public boolean readRssi(String address) {
        BluetoothGatt bluetoothGatt = gattArrayMap.get(address);
        return bluetoothGatt != null && bluetoothGatt.readRemoteRssi();
    }
    
    
    public void remove(String address) {
        BluetoothGatt bluetoothGatt = gattArrayMap.get(address);
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            gattArrayMap.remove(address);
        }
    }
    
    public void disConnect(String address) {
        BluetoothGatt bluetoothGatt = gattArrayMap.get(address);
        if (bluetoothGatt != null) {
            bluetoothGatt.disconnect();
            gattArrayMap.remove(address);
        }
    }
    
    
    @Override
    public void onDestroy() {
        gattArrayMap.clear();
        super.onDestroy();
    }
    }
    

    相关文章

      网友评论

      • e206c3b457f5:服务绑定了,但是在发送信息和接收信息的时候有时候发送失败,走的是未绑定服务的回调,一直未找出原因!
        玉树林枫:@dengfuyao 那可以先绑定后再发送,可以看下官方代码http://download.csdn.net/download/luochoudan/9447168,我也是在原基础上修改的
        e206c3b457f5:@玉树林枫 我的也是,特征也是同一个,就是不知道是不是我是不是消息发早了,服务还没绑定还是怎么的
        玉树林枫:@dengfuyao 未绑定服务的回调?我只用一个Service,没有其他Service了,连接和读写数据都是这个Service
      • e206c3b457f5:楼主,有完整的demo吗?
        玉树林枫:绑定服务就可以了,如果需要回调数据,可以看看Service和Activity的数据通信

      本文标题:android 低功耗蓝牙BLE多连接,多设备通信

      本文链接:https://www.haomeiwen.com/subject/odjyottx.html