[英]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.