簡體   English   中英

自動連接到BLE設備[Android]

[英]Automatic connecting to a BLE device [Android]

我正在使用應自動使用指定的MAC地址連接到BLE設備的Android應用程序。 基本上,掃描應該在24/7上運行,並且一旦發現設備,服務就應該連接到該設備,並且最好停止掃描。

我設法做到以下幾點:

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();
}

上面的方法是使用庫, 庫應該使BLE更加容易(我嘗試過使用它並且同樣喜歡它很少)基本上,掃描在幾秒鍾內返回了大約一千次相同的設備,而沒有機會先連接到它。 是否有可能讓每個設備在掃描時只被發現一次? 有沒有更合適的方法來實現24/7自動連接搜索?

我還發現,例如,當您僅關閉BLE設備或進入飛行模式時,不會調用BluetoothGattCallback onConnectionStateChange方法。 如果這樣做的話,那將使我的生活更加輕松。

我的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);
            }
        }

只需將connectGatt與autoConnect = true一起使用即可。 它適用於所有Android版本,並且與Nougat中引入的掃描相比,使用方面沒有任何限制。 這樣做將告訴藍牙控制器在檢測到廣告后立即連接到該設備。 請注意,由於不幸的是,當連接到特定的BD地址時,android api缺少“地址類型”參數,因此您可能需要與設備綁定,或者必須是自上次打開藍牙以來通過某些藍牙掃描發現的。

不幸的是,當藍牙打開時,您仍然需要藍牙狀態更改廣播接收器來重新啟動所有功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM