이번 프로젝트를 진행하면서 블루투스기능을 사용하게 되었는데, 페어링과 연결, 관련 상태들이 헷갈려서 정리해두려고 한다.
블루투스 활성화나 디바이스 검색 등 전체적인 블루투스 기능을 제공하는 클래스
검색된 주변 장치들을 나타내는 클래스로 장치 정보를 얻거나 연결 시도할 수 있음.
실제 데이터 전송을 위한 연결관련 기능 제공.
나중에 또 찾아볼 것 같아서 사용했던 코드 스니펫도 남겨둔다.
블루투스로 연결할 디바이스를 스캔하는 방법
BluetoothManager를 통해 adapter에 대한 참조를 얻는다.
val bluetoothManager: BluetoothManager =
requireContext().getSystemService(Context.BLUETOOTH_SERVICE) as? BluetoothManager
?: throw Exception("Bluetooth is not supported by this device")
mBtAdapter = bluetoothManager.adapter
mBtAdapter.bondedDevices로 기존에 페어링 된 디바이스 목록을 가져온다.
mBtAdapter.bondedDevices.toList().forEach {
viewModel.updateConnectableList(it)
}
새로운 페어링 가능한 디바이스를 찾는다.
mBtAdapter.startDiscovery()
startDiscovery()를 호출하면 이에 대한 응답을 브로드캐스트 리시버로 받을 수 있다.
inner class BluetoothDeviceReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) {
Timber.tag("bluetooth").d(intent.action.toString())
when (intent.action) {
BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
viewModel.scanning.postValue(false)
}
BluetoothDevice.ACTION_FOUND -> {
val device =
intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
if (device != null) {
updatePairedDevicesList(device)
}
}
}
}
}
디바이스와 연결하기
private val callback = object : BluetoothGattCallback() {
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
super.onConnectionStateChange(gatt, status, newState)
when (newState) {
STATE_CONNECTED -> {
// 연결됨
}
STATE_DISCONNECTED -> {
// 연결 해제
}
else -> {
}
}
}
}
selectedDevice.connectGatt(requireContext(), true, callback).connect()
대략 이런 식으로 사용했다.