我正在开发一个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);
}
}
答案 0 :(得分:2)
只需将connectGatt与autoConnect = true一起使用即可。这适用于所有Android版本,与扫描相比,使用没有限制,如Nougat中所介绍的。这样做会告诉蓝牙控制器在检测到广告后立即连接到设备。请注意,因为android api不幸缺少"地址类型"连接到特定BD地址时的参数,您需要与设备绑定,或者自上次打开蓝牙以来必须通过某些蓝牙扫描发现它。
不幸的是,当蓝牙打开时,您仍需要蓝牙状态更改广播接收器来重启所有内容。