Ожидаемое поведение:
- Вызов mBtAdapter.setName("NEW_NAME")
- Метод возвращает (успех)
Код: Выделить всё
true - ACTION_LOCAL_NAME_CHANGED трансляция запущена
- Перейдите к следующим шагам
- setName() возвращает
Код: Выделить всё
true - Но ACTION_LOCAL_NAME_CHANGED трансляция НИКОГДА не запускается
- Наблюдается на OnePlus Nord 4 и некоторых других устройства
- Похоже, это происходит чаще на устройствах Android 10+.
- Может быть связано с быстрой последовательной сменой имен.
- Возможно, связано с улучшениями конфиденциальности Bluetooth в Android.
Я реализовал гибридный подход, который сочетает в себе прослушивание широковещательной передачи с резервным механизмом тайм-аута:**
Код: Выделить всё
// 1. Store expected name and set timeout handler
mExpectedBTName = name;
boolean success = mBtAdapter.setName(name);
if (!success) {
// Immediate failure - handle it
sendEvent(EVENT_BT_ADVERTISING_FAILED, null);
return;
}
// 2. Set fallback timeout (3 seconds)
mNameChangeTimeoutHandler = new Handler(Looper.getMainLooper());
mNameChangeTimeoutHandler.postDelayed(new Runnable() {
@Override
public void run() {
String updatedName = mBtAdapter.getName();
if (name.equalsIgnoreCase(updatedName)) {
// Name was changed, broadcast just didn't fire
startAdvertising();
} else {
// Name change actually failed
sendEvent(EVENT_BT_ADVERTISING_FAILED, null);
}
mNameChangeTimeoutHandler = null;
}
}, 3000);
// 3. Broadcast receiver
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
// Cancel timeout if broadcast is received
if (mNameChangeTimeoutHandler != null) {
mNameChangeTimeoutHandler.removeCallbacksAndMessages(null);
mNameChangeTimeoutHandler = null;
}
String currentBTName = intent.getExtras().getString(BluetoothAdapter.EXTRA_LOCAL_NAME);
if (mExpectedBTName != null && currentBTName.equalsIgnoreCase(mExpectedBTName)) {
mExpectedBTName = null;
startAdvertising();
}
}
}
- Известна ли это проблема стека Android Bluetooth? Кто-нибудь еще сталкивался с этим?
- Есть ли лучший способ надежно определить момент завершения изменения имени Bluetooth?
- Есть ли какие-либо риски, связанные с резервным опросом? Может ли проверка getName() быть ненадежной в определенных состояниях?
- Минимальный SDK: 24
- Целевой SDK: 33
- Приложение React Native со встроенным модулем Bluetooth
- Использование разрешений BLUETOOTH_CONNECT, BLUETOOTH_SCAN, BLUETOOTH_ADVERTISE
Подробнее здесь: https://stackoverflow.com/questions/798 ... changed-br