自动连接到BLE设备[Android]

时间:2017-06-08 22:32:06

标签: android bluetooth connection bluetooth-lowenergy device

我正在开发一个Android应用程序,它应该使用指定的MAC地址自动连接到BLE设备。 基本上扫描应该全天候运行,一旦发现设备,服务应该连接到它,理想情况下停止扫描。

我设法做的是:

public void startBluetoothScan() {
    if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION)
            == PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        if (!scanning) {
            service.startScan();
        }
    }
}

这是整体方法:

private void configBluetooth() {
    BluetoothConfiguration config = new BluetoothConfiguration();
    config.context = getApplicationContext();
    config.bluetoothServiceClass = BluetoothLeService.class; // BluetoothClassicService.class or BluetoothLeService.class
    config.bufferSize = 1024;
    config.characterDelimiter = '\n';
    config.deviceName = "Your App Name";
    config.callListenersInMainThread = true;

    // Bluetooth Classic
    config.uuid = null; // Set null to find all devices on scan.

    // Bluetooth LE
    config.uuidService = UUID_HRS;
    config.uuidCharacteristic = UUID_HRD;
    config.transport = BluetoothDevice.TRANSPORT_LE; // Only for dual-mode devices

    BluetoothLeService.init(config);
    service = (BluetoothLeService) BluetoothLeService.getDefaultInstance();

    service.setOnScanCallback(new BluetoothLeService.OnBluetoothScanCallback() {
        @Override
        public void onDeviceDiscovered(BluetoothDevice device, int rssi) {
            Log.d("Found device address", device.getAddress());
            if (device.getAddress().equals(UserHRMAddress)){
                if (!deviceList.contains(device)) {
                    Log.d("Connecting to", device.getAddress());
                    connectDevice(device);
                    deviceList.add(device);
                }
            }
        }

        @Override
        public void onStartScan() {
            Log.d("Started Scan", "now");
            scanning = true;
        }

        @Override
        public void onStopScan() {
            Log.d("Stopped Scan", "now");
            scanning = false;
            startBluetoothScan();
        }
    });

    service.startScan();
}

上面的方法是this库的使用,它应该使BLE更容易(我尝试原始并且同样喜欢它)基本上扫描在几秒钟内返回相同的设备大约一千次,而没有有机会先连接它。是否有可能让每台设备在扫描时只被发现一次?有没有更合适的方法来实现自动连接的全天候搜索?

我还发现,BluetoothGattCallback onConnectionStateChange方法例如只需关闭BLE设备或进入飞行模式即可调用。如果它这样做,它将使我的生活更轻松。

我的BluetoothGattCallback方法的相关部分如下所示:

@Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                Log.d("onConnectionStateChange", gatt.getDevice().getName());
                mBluetoothGatt.discoverServices();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                //mBluetoothAdapter.startLeScan(mLeScanCallback);
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.d("Status", "success");
                heartRateService = gatt.getService(UUID_HRS);
                batteryLevelService = gatt.getService(Battery_Service_UUID);

                if (batteryLevelService != null) {
                    batteryLevelCharacteristic =
                            batteryLevelService.getCharacteristic(Battery_Level_UUID);
                }


                if (heartRateService != null) {

                    heartRateCharacteristic = heartRateService.getCharacteristic(UUID_HRD);
                    boolean res = gatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER);
                    gatt.setCharacteristicNotification(heartRateCharacteristic, true);

                    try {
                        BluetoothGattDescriptor descriptor = heartRateCharacteristic.getDescriptor(
                                UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG));

                        descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);

                        mBluetoothGatt.writeDescriptor(descriptor);
                    } catch (Exception ex) {
                        Log.e(TAG, "wuuuuut?");

                    }


                }

            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

1 个答案:

答案 0 :(得分:2)

只需将connectGatt与autoConnect = true一起使用即可。这适用于所有Android版本,与扫描相比,使用没有限制,如Nougat中所介绍的。这样做会告诉蓝牙控制器在检测到广告后立即连接到设备。请注意,因为android api不幸缺少"地址类型"连接到特定BD地址时的参数,您需要与设备绑定,或者自上次打开蓝牙以来必须通过某些蓝牙扫描发现它。

不幸的是,当蓝牙打开时,您仍需要蓝牙状态更改广播接收器来重启所有内容。