Просто потому, что комментарии для этого не годятся, позвольте мне дать вам список вещей, которые вам следует сделать, прежде чем вы сможете действовать с помощью Bluetooth. (извиняюсь, это Java, потому что это то, что у меня есть прямо сейчас, но очень легко перевести на Kotlin, если необходимо)
Я делаю это для BT LE (с низким энергопотреблением), что является предпочтительным путь по .. очевидным причинам.
- Вы добавляли разрешения в манифест? Вам нужно что-то вроде
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH"/>
Убедитесь, что Bluetooth существует и включен ...
// Does BLE exist?
if(getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
final BluetoothManager manager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
Теперь, когда у вас есть менеджер, вам нужно получить BluetoothAdapter
:
BluetoothAdapter bluetoothAdapter = manager.getAdapter();
Все это нормально в onCreate, но имейте в виду, что вы должны проверять, включен ли BT каждый раз, когда пользователь возобновляет активность (поскольку это могло быть выключено / отключено / отозвано / и т.д. c).
Вероятно в onResume:
// obviously, you need to check that Bt adapter isn't null and all that,
// otherwise you ought to go back and "construct" it again, check permissions, etc.
adapter = getBTAdapter(); // do all the checks in there...
boolean bluetoothEnabled = adapter != null && adapter.isEnabled();
Если радиомодуль BT выключен (пользователь отключил его), вы можете включить его программно, , если у вас есть соответствующее разрешение (что я думаю, это администратор BT или аналогичный, вам придется поискать этого, потому что это было давно).
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Я думаю, что это было.
Поскольку BT - это радио, которому требуется питание, потребуется некоторое время (секунды), чтобы включиться и стать доступным. Для этого вам нужно «слушать» с помощью еще одного широковещательного приемника ...
Другими словами, действие вызовет намерение (startActivityForResult(...)
), сообщающее Android включить BT, вы подпишетесь на это трансляция для прослушивания обратного вызова. Как только android проинформирует вас о том, что BT включен, вы можете go вернуться к шагу 1 и начать проверять, включен ли он, у вас есть разрешение и т. c.
Обратный вызов - если я не забыл слишком много ... выглядело как
public void onReceive(Context context, Intent intent) {
Там вы должны проверить различные BluetoothAdapter
состояния ... среди них:
BluetoothAdapter.ACTION_STATE_CHANGED
Это сигнализирует, что состояние изменилось, но другое вложенное состояние, если необходимо для определения до какого состояния ...
final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE);
switch (state) {
case BluetoothAdapter.STATE_OFF:
case BluetoothAdapter.STATE_TURNING_OFF:
case BluetoothAdapter.STATE_TURNING_ON:
case BluetoothAdapter.STATE_ON:
}
Это все те, которые вам небезразличны (отметьте перечисление BluetoothAdapter для получения дополнительной информации).
В ON
вы знаете, что BT включен ... так что ...
Теперь вы можете сообщить адаптеру, что хотите scan
. ..
adapter.startLeScan(callback);
(не забудьте позвонить stopLeScan(callback)
, когда закончите).
При обнаружении каждого устройства будет вызываться callback
с информацией, необходимой для попытки подключения и сопряжения (при необходимости).
Сигнатура обратного вызова (LeScanCallback
) выглядит примерно так:
public void onScan(final BluetoothDevice device, int rssi, byte[] record);
(я печатаю по памяти, так что это может быть другое имя, но вы уловили идею)
Это, насколько я помню, старый API.
API 21 имеет ScanSettings.Builder()
, где вы можете указать, как вы хотите сканировать, но по сути это аналогичный метод. Запустите сканирование, передайте обратный вызов и дождитесь появления результатов.
У вас также есть разные режимы:
SCAN_MODE_BALANCED: баланс эффективности батареи и скорости сканирования
SCAN_MODE_LOW_LATENCY: предпочитать скорость сканирования батарея
SCAN_MODE_LOW_POWER: эффективность батареи предпочтительнее скорости сканирования
SCAN_MODE_OPPORTUNISTI C: не помню :) Я думаю это было использовать результаты других сканеров «вокруг» вас. Никогда не использовал его.
После того, как вы определили устройство, которое искали, BluetoothDevice
имеет все необходимое, чтобы сообщить BT о «подключении» к нему.
public void onScanResult(int callbackType, ScanResult scanResult) {
^ это подпись «нового» сканера.
Из этого ScanResult вы можете сделать:
int rssi = result.getRssi();
BluetoothDevice device = result.getDevice();
String advertiseName = device.getName();
String macAddress = device.getAddress();
Если сканирование завершится неудачно по какой-либо причине, вы получите обратный вызов на onScanFailed(int errorCode)
. И снова, есть разные «причины» (проверьте errorCode
), почему сканирование не удалось.
Помните, я могу смешивать API 18 или API 21 здесь, но концепция очень похожа в обоих .
После того, как вы наконец получили адрес MA C устройства ... вы можете попросить адаптер попытаться подключиться к нему:
BluetoothDevice device = adapter.getRemoteDevice(macAddress);
device.connectGatt(context, false, anotherCallback);
Обратный вызов имеет BluetoothGattCallback
, и опять же, среди них есть несколько методов onConnectionStateChange...
На этом этапе вам следует больше узнать о том, как работает Bluetooth (и как он работает на Android) потому что существуют различные режимы (Gatt - односторонний) работы с BT. Невозможно знать каждый и как / что вы хотите делать после подключения.
Практическое правило будет: убедитесь, что вы готовы к повторному соединению или повторному запросу разрешений, потому что в конечном итоге это выбор пользователя: отключить, выключить, уйти, отозвать разрешение и т. д. c. в в любой точке при этом.
Удачи!