Я работаю над приложением для Android, которое программно меняет имя устройства Bluetooth с помощью BluetoothAdapter.setName(). Приложению необходимо знать, когда изменение имени завершится, чтобы инициировать последующие действия (запуск рекламы BLE). Ожидаемое поведение:
Но ACTION_LOCAL_NAME_CHANGED трансляция НИКОГДА не запускается
Затронутые устройства/сценарии:
Наблюдается на OnePlus Nord 4 и некоторых других устройства
Похоже, это происходит чаще на устройствах Android 10+.
Может быть связано с быстрой последовательной сменой имен.
Возможно, связано с улучшениями конфиденциальности Bluetooth в Android.
**Текущее Обходной путь/решение:
Я реализовал гибридный подход, который сочетает в себе прослушивание широковещательной передачи с резервным механизмом тайм-аута:**
Я работаю над приложением для Android, которое программно меняет имя устройства Bluetooth с помощью BluetoothAdapter.setName(). Приложению необходимо знать, когда изменение имени завершится, чтобы инициировать последующие действия (запуск рекламы BLE). [b]Ожидаемое поведение:[/b] [list] [*]Вызов mBtAdapter.setName("NEW_NAME")
[*]Метод возвращает [code]true[/code] (успех)
[*]ACTION_LOCAL_NAME_CHANGED трансляция запущена
[*]Перейдите к следующим шагам
[/list] [b]Наблюдаемое поведение на некоторых устройствах:[/b] [list] [*]setName() возвращает [code]true[/code]
[*][b]Но ACTION_LOCAL_NAME_CHANGED трансляция НИКОГДА не запускается[/b]
[/list] [b]Затронутые устройства/сценарии:[/b] [list] [*]Наблюдается на OnePlus Nord 4 и некоторых других устройства
[*]Похоже, это происходит чаще на устройствах Android 10+.
[*]Может быть связано с быстрой последовательной сменой имен.
[*]Возможно, связано с улучшениями конфиденциальности Bluetooth в Android.
[/list] **Текущее Обходной путь/решение: Я реализовал гибридный подход, который сочетает в себе прослушивание широковещательной передачи с резервным механизмом тайм-аута:** [code]// 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(); } } } [/code] [b]Вопросы:[/b] [list] [*][b]Известна ли это проблема стека Android Bluetooth?[/b] Кто-нибудь еще сталкивался с этим?
[*][b]Есть ли лучший способ надежно определить момент завершения изменения имени Bluetooth?[/b]
[*][b]Есть ли какие-либо риски, связанные с резервным опросом?[/b] Может ли проверка getName() быть ненадежной в определенных состояниях?