Android Bluetooth: список сопряженных устройств

#android #bluetooth #android-bluetooth

#Android #bluetooth #android-bluetooth

Вопрос:

У меня есть устройство Bluetooth с профилем SPP и версией Bluetooth 2.1.
У меня есть приложение, которое подключается к этому устройству и взаимодействует с ним. Устройство использует метод сопряжения «Просто работает».

Я столкнулся с проблемой на некоторых телефонах, таких как Samsung Galaxy tablet, Galaxy S.

Проблема в том, что после выхода пользователя из приложения я закрываю сокеты и отключаюсь от устройства. После успешного отключения наблюдается, что запись устройства удаляется из списка сопряженных устройств.

Ответ №1:

Я не работал с планшетами, но я написал приложение, которое использовало SPP для телефонов Android. Я обнаружил, что для обеспечения стабильности Bluetooth мне нужно вручную подключиться к устройству, с которым я хочу общаться. Мы использовали приведенный ниже код, чтобы инициировать соединение из приложения, и оно должно сохранить соединение так же, как если бы вы выполнили сопряжение вручную через меню настроек.

Вот общий порядок действий: 1) Зарегистрируйте BroadcastReceiver для прослушивания устройства BluetoothDevice.ACTION_BOND_STATE_CHANGED
2) После обнаружения устройства у вас должен быть объект BluetoothDevice.
3) Используйте отражение для вызова метода ‘createBond’ в объекте BluetoothDeviceObject
3a) Дождитесь событий изменения состояния соединения, прежде чем открывать сокеты

 BluetoothDevice device = {obtained from device discovery};
Method m = device.getClass().getMethod("createBond", (Class[])null);
m.invoke(device, (Object[])null);

int bondState = device.getBondState();
if (bondState == BluetoothDevice.BOND_NONE || bondState == BluetoothDevice.BOND_BONDING)
{
    waitingForBonding = true; // Class variable used later in the broadcast receiver

    // Also...I have the whole bluetooth session running on a thread.  This was a key point for me.  If the bond state is not BOND_BONDED, I wait here.  Then see the snippets below
    synchronized(this)
    {
        wait();
    }
}
  

4) Дождитесь изменения состояния связи с BOND_BONDING на BOND_BONDED

Внутри приемника широковещательной передачи:

 public void onReceive(Context context, Intent intent)
{
    if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction()))
    {
        int prevBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
        int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);

        if (waitingForBonding)
        {
            if (prevBondState == BluetoothDevice.BOND_BONDING)
            {
                // check for both BONDED and NONE here because in some error cases the bonding fails and we need to fail gracefully.
                if (bondState == BluetoothDevice.BOND_BONDED || bondState == BluetoothDevice.BOND_NONE)
                {
                    // safely notify your thread to continue
                }
            }
        }
    }
}
  

5) Откройте сокеты и общайтесь

Вы также можете использовать метод «removeBond» с помощью отражения, чтобы удалить ваше устройство из списка сопряжения.

Надеюсь, это поможет!

Ответ №2:

Если сопряжение происходит в результате подключения вашего приложения, я предполагаю, что некоторые устройства будут рассматривать это как временное сопряжение и не сохранят устройство в списке сопряженных устройств после отключения соединения. Чтобы сохранить устройство в списке сопряженных, вам следует выполнить сопряжение вручную через меню настроек Bluetooth. После сопряжения ваша программа может подключаться / отключаться, и устройство останется в списке сопряженных.

Комментарии:

1. Где я должен изучить детали этого временного поведения сопряжения; Документация Android или документы спецификации Bluetooth 2.1? Если это проблема с Android, она должна воспроизводиться на всех телефонах. Или это связано с реализацией производителя в стеке Bluetooth?

2. Это зависит от производителя, от того, какую опцию он предоставляет для сопряжения / соединения, а не просто для аутентификации для временного подключения. Обычно явное действие для сопряжения (которое также подразумевает сохранение сопряженного устройства, выполняется через системное меню настроек Bluetooth)

Ответ №3:

Я также столкнулся с той же проблемой с Sony Xperia X10. Мне удалось заставить его «запомнить» сопряжение, изменив настройки уровня безопасности на стороне устройства Bluetooth (поскольку я также разрабатываю устройство).

Я не уверен в объяснении «временного сопряжения», которое зависело бы от производителя, не имеет особого смысла, что разные телефоны будут по-разному реагировать на соединение с одним и тем же устройством.

Однако для меня проблема заключается в неограниченной части. Обычно происходит сбой стека Bluetooth, когда пользователь отключает устройство, в то время как приложение подключено в фоновом режиме. Я до сих пор не понял, как правильно управлять событием ACTION_BOND_STATE_CHANGED.

Комментарии:

1. Можете ли вы сказать мне, какие настройки уровня безопасности необходимы для запоминания устройства в списке сопряженных устройств? Я могу легко воспроизвести это на планшетах с Android 3.0 , поэтому я подумал, что это связано с версией Android.

2. Я изменил прошивку устройства, чтобы ответить, что это устройство типа «только для отображения», когда оно получает запрос на объявление своих возможностей ввода-вывода с телефона (ранее для него было установлено значение «без ввода и без вывода»).). Это согласование является частью протокола сопряжения Bluetooth и задокументировано в спецификациях Bluetooth, но я понятия не имею, почему это повлияло на поведение телефона.