#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, но я понятия не имею, почему это повлияло на поведение телефона.