Определение подключенности Bluetooth под Android

в 12:05, , рубрики: android, bluetooth, Песочница, метки: ,

Итак, передо мной возникла задача — программно определить подключенно ли какое-то из сопряженных устройств в данный момент к моему телефону посредством Bluetooth. Долго и безуспешно выискивал в сети какое-либо готовое решение по этому поводу, однако удалость найти лишь только указание на то, что есть возможность отслеживания события подключения по Bluetooth. Но ведь программа может быть запущена уже после события, следовательно, это мне не подошло.

Собственно после этого (и листания разделов посвященных Bluetooth в официальной документации Android) и пришла мысль попробовать соединяться с каждым сопряженным устройством, а далее смотреть на успех операции: если успешно — значит устройство в зоне покрытия и подключено. Затея оказалась успешной.
Однако, на пути к ее реализации ожидал еще подвох:

BluetoothSocket bs = device.createRfcommSocketToServiceRecord(MY_UUID);
bs.connect();

Этот код создания клиентского подключения никак не хотел выполняться, всегда возвращая ошибку «Service discovery failed». Снова поиск, чтение и выявление факта массы жалоб на такую же проблему. Советы же по решению данной проблемы сводились к одному: предложению различных значений для MY_UUID. Я перепробовал N-ное количество различных UUID из этих советов, но ни с одним соединение между Windows Mobile и Android получить не удалось. Интересный момент: при попытке соединения у «спящего» WM-коммуникатора загорался дисплей. То есть соединение все же инициализируется, но по каким-то причинам не устанавливается. Решение нашлось у соотечественника:

Method m = device.getClass().getMethod("createRfcommSocket",new Class[] { int.class });
socket = (BluetoothSocket)m.invoke(device, Integer.valueOf(1));

И данный способ действительно работает безотказно.

Общий же код проверки Bluetooth'а на подключенность выглядит примерно так:

boolean checkConnected() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
boolean connected = false;
for (BluetoothDevice device : mBluetoothAdapter.getBondedDevices()) {
try {
try {
Method m = device.getClass().getMethod("createRfcommSocket",new Class[] { int.class });
try {
BluetoothSocket bs = (BluetoothSocket) m.invoke(device,Integer.valueOf(1));
bs.connect();
connected = true;
Log.d(TAG, device.getName() + " - connected");
break;
} catch (IOException e) {
Log.e(TAG, "IOException: "+e.getLocalizedMessage());
Log.d(TAG, device.getName() + " - not connected");
}
} catch (IllegalArgumentException e) {
Log.e(TAG, "IllegalArgumentException: "+e.getLocalizedMessage());
} catch (IllegalAccessException e) {
Log.e(TAG, "IllegalAccessException: "+e.getLocalizedMessage());
} catch (InvocationTargetException e) {
Log.e(TAG, "InvocationTargetException: "+e.getLocalizedMessage());
}
} catch (SecurityException e) {
Log.e(TAG, "SecurityException: "+e.getLocalizedMessage());
} catch (NoSuchMethodException e) {
Log.e(TAG, "NoSuchMethodException: "+e.getLocalizedMessage());
}
}
return connected;
}

Конечно, работает код не молниеносно. Но тем не менее, код работает и функцию свою выполняет, тем более, что других решений мне найти не удалось. В связи с тем, что опыт работы в Андроид у меня не такой большой, возможно, в коде есть что еще подправить или существует какое-то другое решение. Но это уже подскажут знатоки.

Автор: bartwell


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js