나는 현재 회사에서 블루투스 SDK 관련 업무를 맡고 있다. 그래서 블루투스 관련 문서를 많이 보는 편인데, 안드로이드 공식 사이트에 나와있는 블루투스 관련 설명이 하나같이 다 불친절하다고 느꼈다.
사실 문서만이 아니다. 실제로 API를 사용해보면 에러 코드가 별 다른 구분 없이 다 동일한 코드로 떨어진다던가, 블루투스 전송 시 API 레벨에서 일련의 큐 구조와 같은 메시지 관리 로직이 없어 성공, 실패 등등의 응답이 떨어지기 전에 전송하면 문제가 발생한다던가 ...
사실 이러한 내용들은 난 공식 문서에서 알려줘야 하는 부분이라고 생각하는데, 공식 문서에는 하나같이 내용들이 부실하며, 그냥 단순한 코드 스니펫만 줄줄 나와있다.
그래서 답답했던 나머지 내가 여태껏 안드로이드의 Bluetooth API를 사용하면서 이해가 되지 않거나, 궁금했던 내용, 삽질했던 내 기록들을 담은 BLE 시리즈를 준비해보았다.
오늘은 그 첫번째 이야기, Auto Connect에 관한 내용이다.
안드로이드 공식 문서를 확인해보면 다음과 같은 코드 스니펫을 볼 수 있다.
var bluetoothGatt: BluetoothGatt? = null
...
bluetoothGatt = device.connectGatt(this, false, gattCallback)
매개변수는 앞에서부터 Context
, boolean
, BluetoothGattCallback
를 입력받는다.
Context와 BluetoothGattCallback은 그렇다 쳐도, 2번째 값인 autoConnect(boolean)
은 어떤 친구일까?
autoConnect : 이용 가능한 즉시 블루투스 기기에 자동 연결할지 나타내는 부울
Android Developer
그렇다. 번역된거라 이해가 바로 되지는 않지만, 여러 번 읽다 보면 뭔가 자동으로 다시 연결해주고 싶을 때 사용하는 플래그 같다.
이 플래그를 설정하면 어떠한 매커니즘이 동작할까?
위의 매개변수 autoConnect
에 전달하는 값에 따라
true
: Auto Connectfalse
: Direct Connect로 동작한다.
용어에서도 알 수 있듯이, 직접 연결을 의미한다.
Callback
으로 에러를 반환한다.또한 Direct Connect는 Auto Connect에 비해 우선순위가 높게 처리되기 때문에 만약 Auto Connect를 시도하고 있는 연결이 있다면 잠시 중단하고 Direct Connect를 우선적으로 처리하게 된다.
이건 자동 연결을 의미하며, Direct Connect의 반대 성격을 가진다.
또한 동시에 여러 개의 Auto Connect 연결을 가질 수 있다. 그래서 디바이스 신호가 약해졌거나, 꺼졌거나 하는 등의 이유로 Connection을 Lost 해도 끊임없이 재연결을 시도한다.
근데, 만약 이 때 disconnect()
또는 close()
를 호출하여 연결이 끊어지면 다시 연결을 시도하지 않는다.
이 외에도 연결할 때 차이가 있다. Direct Connect가 30초라는 시간 제한을 가진 대신 우선순위가 더 높기 때문에 더 짧은 주기로 연결 가능한 Advertising Packet
을 검색한다. 그래서 Auto Connect보다 연결이 더 빠르게 성립된다.
사실 이 차이는 Android 10 부터는 줄어들었다고 한다. Direct Connect를 처리하는 동안 Auto Connect는 멈추지 않고, Direct Connect에도
Whitelist
개념이 도입되어 Auto Connect와 비슷하게 동작된다고 한다.
autoConnect = true
로 연결이 성립된다면 연결된 디바이스에 대한 정보가 캐시되어 저장된다. 이게 WhiteList
에 등록되는 것인데, 무조건 등록되는 것은 아니고 아래의 조건 중 하나 이상을 만족해야 한다.
이 중에 한 가지의 조건도 성립되지 않는다면 whiteList
에 추가되지 못하고, 재연결을 시도하지 않게 된다.
백그라운드에서 지속적인 연결이 필요한 경우에 사용할 수 있겠다. 나와 같은 경우 개발 중인 SDK 중 백그라운드에서도 지속적인 데이터 수신이 필요한 기능이 있는데, Connection이 항상 유지될 수가 없으므로 이럴 때 Auto Connect를 이용해 다시 연결을 시도하는 방식을 생각해보았다.
다만 백그라운드에서 블루투스 Connection을 유지하기 위해 Foreground Service를 이용해 백그라운드에서도 연결이 유지되도록 작업해주었다.
Auto Connect가 연결이 해제되어도 다시 연결을 해주기 때문에 더 좋아보일 수도 있지만, Direct Connect 보다 우선순위가 낮아 연결이 늦게 성립된다.
또, 앱이 종료되면 디바이스 정보를 캐시했던 WhiteList가 날아가서 재연결을 시도하지 않는다. 이는 활용에서도 언급했듯이 Foreground Service를 이용해 백그라운드에서도 어느 정도의 연결 유지는 가능하다. 다만 이 Service도 시스템에 의하여 종료되는 등의 이유로 앱의 프로세스가 완전히 kill 된다면 재연결을 다시 시도하지 않는다. 이는 단말기가 Shutdown 해도 동일하다.
나와 같은 경우 위의 상황을 대비해 MAC Address를 따로 저장하여 BroadcastReceiver를 통해 부팅 이벤트를 수신받고, Foreground Service를 이용해 재연결 하도록 작업하려고 했다.
https://stackoverflow.com/questions/40156699/which-correct-flag-of-autoconnect-in-connectgatt-of-ble
잘봤습니다.