android] ble scanning의 메모
회사에서 안드로이드 개발을 하면서 비콘을 스캔해야하는 기능을 구현해야 했습니다.
진행하면서 고민했던 부분에 대해서 기록했습니다.
1. 권한받기
이 기능을 구현하기 위해서 블루투스 권한을 받아야하고, 위치정보와 관련된 권한도 받아야 했다.
그럼 우선 권한 부분에 대해서는
- 블루투스 스캔 권한 받기
- 위치 권한 받기
- 블루투스가 꺼져있을 경우 킬 수 있도록 안내하기
최근에는 블루투스 관련 이어폰이나 시계가 많아 블루투스를 꺼놓을 일이 거의 없지만,
현실적으로는 킬수도 있고 안킬 수도 있기 때문에 키지않았다면 킬 수 있도록 안내하는게 맞는 것 같다고 생각했다.
더 나아가 중간에 블루투스를 끌 경우에는 어떻게 해야할지에 대해 고민하는 것도 좋다고 생각한다.
2. BluetoothLeScanner 함수
블루투스를 스캔하는 함수와 비콘을 스캔하는 함수가 따로 있다.
애초에 블루투스는 연결해서 통신하는 것을 전제로 하기 때문에 모든 블루투스 장치를 검색하고, 통신 여부를 본다든지와 같은 연결과 관련된 동작들이 들어있다.
하지만 비콘은 비콘만을 검색하며, 연결은 안한다는 것이 전제가 포함되어있어, 비콘 스캔과 관련된 동작을 위해서라면 BluetoothLeScanner 라는 함수를 쓰는게 낫다.
이부분은 아마 비콘 스캔과 관련된 초기 지식을 가지고 있다면 너무나도 당연한 이야기지 않냐는 생각이 들 수도 있다.
하지만 필자는 BluetoothLeScanner 함수를 따로 지원하는 지 몰랐고, BluetoothManager 관련 클래스에서 구현해서 비콘 스캔 성능이 문제가 되어 어떻게 해야할지 한참을 해매면서 검색했다.
이건 초기 지식보다는 안드로이드 개발에서 비콘 스캔 기능을 따로 지원하는지에 대한 사전 정보가 부족해서 발생한 문제였다.
물론 라이브러리를 쓰면 된다는 말씀도 맞다. AltBeacon과 같은 잘되어있는 라이브러리가 있지만, 써보려고하니 여러 종류의 비콘을 다 스캔하려니 잘안되서 사용하지않았다. 지금이면 가능할 것 같은데, 그때 당시에는 그 문제를 어떻게 해결해야할 줄 몰라서 못 썼다는 이유가 크다.
3. flushPendingScanResults 함수
비콘 스캔을 진행하다보면 장시간 비콘 스캔을 했을 때, 더이상 비콘이 스캔되지 않는 문제도 있었다.
일정 시간되면 껐다가 켜야한다. 라는 정보는 알고 있었지만 언제 어느시점에서 그렇게 해야할 지는 그때 그때마다 달라서 어떻게 해야할지 고민했다.
혹시나 버퍼 문제일까 생각하며 flushPendingScanResults 함수를 찾았고, 주기적으로 얘를 사용하니 해결이 되었다.
다른 해결 방법으로는 그냥 ble 스캔 자체를 껐다가 키면 된다.
4. background scan
백그라운드에서 동작하게 하려면 어떻게 해야할지 고민할 필요가 있다.
안드로이드에서는 scanFilter가 없으면 스캔이 금방 중단되는 문제가 있다.
filter로 Mac Address나 beacon에 설정된 name을 넣으면 되겠지만, 이때 등록되는 필터는 '포함하는' 이런 동작이 없기 때문에 소수의 비콘을 찾을 때에만 사용된다. (이름 뒤에 띄어쓰기 있을 땐 어떻게 되는지 확인 안해봤다.)
해결 방법은 다양하겠지만, 일단 필자는 Mac Address 여러개 등록으로 해결했다.
Scan Callback 부분에 이름에다 startWith() 같은 함수를 쓰면 원하는 비콘을 얻을 순 있겠지만, 백그라운드 환경에서는 동작하지 않을 것이다.
5. 마치며
실제 개발하는 동안 이 부분 이외에도 여러 기능을 고려해서 추가했지만, 따로 기록하지는 않았다.
내가 진행한 프로젝트의 기능 100% 다 쓸 필요는 없다고 생각했고, 이 외의 부분에 대해서는 각자의 프로젝트에서 +@로 들어가는 기술이므로 궁금한 부분이나 헷갈리는 부분에 대해서는 서로 소통하면서 해결하는게 나을 거라고 생각했기 때문이다.