Неудачное обнаружение службы с использованием Bluetooth на Android
В настоящее время я работаю над приложением Android, которое подключается к инструменту через Bluetooth, и вам нужно написать строковые команды и получить ответы на строковые ответы. В настоящее время у меня есть соединение/чтение/запись, работающие для TCP/IP через Wi-Fi, и теперь мы пытаемся реализовать Bluetooth. Но я сталкиваюсь с некоторыми препятствиями. Я искал в Интернете, пытаясь найти примеры чего-то подобного и не повезло. Я использую пример ресурса разработчика Android: Bluetooth Chat в качестве моей основной контрольной точки.
Мой текущий код, похоже, работает. Затем он выдает исключение службы обнаружения сбой в точке соединения. Я использую класс DeviceListActivity
для обнаружения и выбора устройства, к которому я хочу подключиться. Он возвращает anActivityResult, а затем мой класс Bluetooth ждет, чтобы он обработал это, а затем подключился к нему. Код ниже почти идентичен Bluetooth Chat App.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(!m_BluetoothAdapter.isEnabled())
{
m_BluetoothAdapter.enable();
}
switch (requestCode) {
case REQUEST_CONNECT_DEVICE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = m_BluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
connect(device);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
}
else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_SHORT).show();
finish();
}
}
}
Это моя функция подключения:
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private void connect(BluetoothDevice device) {
m_Device = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (IOException e) {
}
m_Socket = tmp;
m_BluetoothAdapter.cancelDiscovery();
try {
// This is a blocking call and will only return on a
// successful connection or an exception
m_Socket.connect();
}
catch (IOException e) {
try {
m_Socket.close();
}
catch (IOException e2) {
}
return;
}
}
Надеюсь, все, что я делаю неправильно, просто, но я боюсь, что это никогда не будет так просто. Это мой первый раз, когда я занимаюсь разработкой Bluetooth, и, может быть, я делаю что-то вопиюще неправильно... Но я не уверен, почему я получил отказ службы обнаружения.
Вы можете одновременно находить/находить устройство вручную на телефоне... Это требует кода доступа, но я не думаю, что это проблема, с которой я столкнулся.
Ответы
Ответ 1
Спустя три дня я понял, что благодаря очень полезным сообщениям.
Мне пришлось заменить:
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
с:
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);
и voilà работает!
Ответ 2
По API 15 вы можете использовать следующий метод:
Попробуйте заменить UUID на возвращаемое значение getUuids() метод класса BluetoothDevice
.
То, что сработало для меня, было примерно так:
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
Причина этого в том, что разные устройства поддерживают разные UUID, и, получив UUID устройства с помощью getUuids, вы поддерживаете все функции и устройства.
Еще один интересный новый метод (поддерживаемый с API 14): BluetoothHealth.getConnectionState. Не пробовал, но выглядит многообещающе...
Ответ 3
Это было предлагаемое изменение от анонимного пользователя, пытающееся ответить на принятый ответ.
Одна большая разница между вашим до и после кода - это UUID, который вы передаете. Я нашел здесь свой ответ: http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createRfcommSocketToServiceRecord(java.util.UUID)
Мне пришлось заменить:
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
с:
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
tmp = device.createRfcommSocketToServiceRecord(SPP_UUID);
и вуаля это работает!
Исходный код предназначен для приложения peer to peer android. Нет смысла использовать UUID приложения при подключении к простому устройству последовательного Bluetooth-устройства. То почему открытие терпит неудачу.
Ответ 4
Итак, как упоминалось выше, дело в том, что вам нужно использовать UUID, который ожидает сервер.
Если вы подключаетесь к устройству Bluetooth, например, к гарнитуре или мыши, вам необходимо проверить, какие UUID устройства прослушивает. Вы можете видеть UUID как это.
UUID[] uuids = bluetoothDevice.getUuids();
И если вы хотите знать, что означают эти UUID, см. this.
Ответ 5
Это очень старый вопрос, но я обнаружил, что использование createInsecureRfcommSocketToServiceRecord()
вместо createRfcommSocketToServiceRecord()
вместе с ранее упомянутым getUuids()
делает трюк для меня
UUID uuid = bluetoothDevice.getUuids()[0].getUuid();
BluetoothSocket socket = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid);