Проблемымаяков + Bluetooth связи (профиль ГАТТ) не работает нормально [BLE]
Я периферийное устройство, которое излучает маяки с определенным идентификатором. С моим смартфоном (который играет центральную роль) выполняется поиск маяка периферийного устройства. Когда он находит правильный маяк, он начинает связь Bluetooth через профиль GATT. В первый раз, когда устройства подключены, данные отправляются от одного к другому правильно, но во второй раз (у меня есть таймер, чтобы попытаться подключить оба устройства каждые 20 секунд), соединение не работает, я не знаю почему ... Я должен убить процесс приложения и снова открыть его, чтобы он снова работал.
Что я сделал
Для маяков, я использую altbeacon, поэтому код для обнаружения маяков в центральном аппарате заключается в следующем:
@Override
public void onBeaconServiceConnect() {
beaconManager.setRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.i(TAG, "Beacon detected!");
if (beacons.size() > 0 && Utils.getUserData(getApplicationContext(), "id").compareTo("-1") != 0) {
if(region.getId1().compareTo(Identifier.parse(identifier))==0) {
Beacon beacon = beacons.iterator().next();
Log.i(TAG, "The first beacon I see is about " + beacon.getDistance() + " meters away. "
+ region.getId1());
String mac = beacon.getBluetoothAddress();
Log.i("MAC", "MAC: "+mac);
CustomBluetoothManager customBluetoothManager = CustomBluetoothManager.getInstance(getApplicationContext());
if(!customBluetoothManager.isScanning()) {
customBluetoothManager.scanLeDevice(true, mac);
}
}
}
}
});
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", Identifier.parse(identifier),
null, null));
} catch (RemoteException e) { }
}
Когда маяк обнаружен, то scanLeDevice называется:
public void scanLeDevice(final boolean enable, String mac) {
target_mac = mac;
mHandler = new Handler();
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
и вот код mLeScanCallback:
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
long epoch = System.currentTimeMillis()/1000;
SharedPreferences prefs = context.getSharedPreferences(
"epoch", Context.MODE_PRIVATE);
long epochStored = prefs.getLong("epoch", 0);
if (device.getAddress().compareTo(MAC) == 0 && after20Seconds) {
prefs.edit().putLong("epoch", epoch).apply();
Log.d("epoch", Long.toString(epoch));
mDeviceAddress = device.getAddress();
final Intent gattServiceIntent = new Intent(context, BluetoothLeService.class);
context.bindService(gattServiceIntent, mServiceConnection, context.BIND_AUTO_CREATE);
}
}
};
Мне пришлось жестко указывать MAC-адрес, поскольку MAC-адрес, который содержит маяки в пакетах, не совпадает с реальным MAC-адресом устройства (это определение BLE, но я точно не знаю, как оно работает).
Наконец, когда данные посылаются, я закрываю и отключить канал Bluetooth® и я пытался отвязать обслуживание тоже, но ничего не работает:
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
disconnect();
close();
unbindService(mServiceConnection);
}
Таким образом, с помощью этого кода, в первый раз что устройства подключены, данные отправляются правильно, но через 20 секунд во второй попытке никогда не будет установлено сообщение.
Вопросы
- Любая идея, что может быть проблема?
- Как работает BLE? В сигнальных пакетах MAC является поддельным по соображениям безопасности. Однако, если я получаю это от маяков сканирования приложений, и я жестко вписываю его в приложение, работа работает ... Я думаю, что это не должно работать.
- Как я могу получить MAC-адрес устройства из пакета маяков?
- Знаете ли вы какой-либо образец, чтобы использовать маяки с Bluetooth-связью?
- Если я остановлю сканирование с помощью метода «mBluetoothAdapter.stopLeScan (mLeScanCallback)», кажется, что сканирование действительно не останавливается ... Это нормально? Журнал непрерывно показывает "BluetoothLeScanner: startRegisteration: mLeScanClients = {org.altbeacon.beacon.service.scanner.CycledLeScannerForLollipop $ 4 @ 5445b45 = android.bluetooth.le.BluetoothLeScanner ......"
Зачем вам нужен альтбекон? от того, что я понимаю. Ваше требование основано на центральных и периферийных ролях gatt, оно вращается вокруг MAC-адресов (ов) устройств. (между тем я также думаю о том, почему его проблема во второй раз, помните, что сталкиваемся с чем-то похожим) – user2450263
Спасибо за ваш ответ! Мне нужны маяки, чтобы знать, когда пользователь находится рядом с периферийным устройством ... Таким образом, мы можем избежать того, что приложение постоянно сканирует устройства Bluetooth, которые находятся вокруг пользователя. – adri1992
'scanLeDevice' и его обратный вызов это так или иначе, вам просто нужно вычислить значение rssi для близости - для вычисления того, находится ли пользователь рядом с устройством. – user2450263