안녕하세요? 닉네임간편입니다. 저번 시간에는 블루투스 권한을 선언하고 블루투스 설정을 했습니다. 이제 블루투스 기능을 사용하기 위해선 근처에 있는 블루투스 기기를 탐색하고 연결해야 합니다. 이번 시간부터는 블루투스 기기 탐색에 대해 알아보겠습니다.
전체 소스는 여기에 있습니다.
https://github.com/creativeduck/MyLED
앱을 미리 사용해보고 계신 분들은, 이 링크를 타고 설치해주시면 됩니다.
https://play.google.com/store/apps/details?id=com.mybest.myled
1. 기기 탐색
기기 탐색은 앞서 만들었던 블루투스 어댑터를 사용해 할 수 있습니다. 이를 통해 주변에 있는 기기를 검색하거나, 혹은 이미 페어링 된 기기 목록에서 연결할 수 있는 블루투스 기기를 찾을 수 있습니다.
기기 검색은 주변에 블루투스를 지원하는 기기가 있는지 찾아본 후, 각 기기의 일부 정보를 요청하는 절차입니다. 이때 검색하려는 블루투스 기기는 검색 가능한 상태가 되어 정보 요청에 수락할 수 있어야 합니다.
요청하는 정보는 기기의 이름, 클래스, 고유 MAC 주소 등이며, 이 정보를 통해 검색을 수행하는 기기(본 예제에서는 스마트폰)가 검색된 기기에 연결하도록 할 수 있습니다.
기기를 탐색하는 과정은 앞서 설명한 듯 주변에 있는 기기를 검색하거나, 혹은 페어링 된 기기 목록에서 연결할 수 있는 기기를 찾는 과정으로 나뉩니다. 이번 시간에는 페어링 된 기기를 탐색하는 과정에 대해 설명드리겠습니다.
2. 페어링 된 기기 탐색
이미 블루투스 기기를 페어링 했다면 페어링 된 기기 집합을 통해 원하는 기기를 연결하는 것이 좋습니다.
시스템에는 이미 페어링 된 장치들의 집합이 존재합니다. 이 집합에 존재하는 페어링 된 장치들의 이름을 다이얼로그를 통해 화면에 띄운 뒤 사용자로 하여금 연결을 원하는 기기를 선택하도록 합니다.
아래부터 자바 코드를 통해 자세히 알아보겠습니다.
Set<BluetoothDevice> pairedDevices;
boolean paired = false;
페어링 된 기기를 탐색하기 위해선 페어링 된 장치 집합이 필요합니다.
따라서 블루투스 장치 집합 변수를 정의합니다.
또한 추후에 필요한 boolean 자료형 변수를 선언합니다.
private void selectPairedDevice() {
pairedDevices = bluetoothAdapter.getBondedDevices();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("장치 선택");
List<String> pairedList = new ArrayList<>();
for(BluetoothDevice device : pairedDevices) {
pairedList.add(device.getName());
}
pairedList.add("취소");
final CharSequence[] devices = pairedList.toArray(new CharSequence[pairedList.size()]);
builder.setItems(devices, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == pairedList.size()-1) {
selectUnpairedDevice();
} else {
bluetoothAdapter.cancelDiscovery();
paired = true;
connectDevice(devices[which].toString(), paired);
}
}
});
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
}
1) 페어링 된 장치 집합 가져오기
getBoundedDevices() 메서드는 페어링 된 기기를 나타내는 BluetoothDevice 객체 집합을 반환하며, 이를 통해 장치 집합을 가져옵니다.
2) 다이얼로그 빌더 생성(AlertDialog.Builder)
다이얼로그를 위한 builder를 생성합니다. 이때 파라미터로 전달하는 것은 context이며, 현재 메인 액티비티 자기 자신을 지칭하는 this를 전달합니다.
setTitle() 메서드를 통해 다이얼로그의 제목을 설정합니다.
3) 페어링된 장치 이름 리스트 만들기
우선 pairedList 리스트를 정의하고 초기화합니다.
이후 for Each 구문을 통해 페어링 된 장치 목록에 있는 모든 장치들의 이름을 이 pairedList에 추가합니다.
또한 취소 버튼도 추가합니다.
4) 요소 선택하기
장치 이름 목록을 toArray를 통해 CharSequence 배열로 만듭니다.
이때 CharSequence 배열로 만드는 이유는, 빌더의 setItems 메서드가 CharSequence 배열을 파라미터로 전달받기 때문입니다.
이후 devices에 있는 요소들을, 즉 장치 이름 목록을 다이얼로그의 요소로 추가합니다.
그리고 OnClickListener를 설정해 특정 요소가 선택될 때 이벤트를 처리합니다.
which는 선택된 아이템의 인덱스를 반환하며, 인덱스 값에 따라 다른 동작을 하도록 합니다.
a) pairedList.size()-1
배열 혹은 리스트의 크기에서 1을 빼면 가장 마지막 인덱스가 나옵니다. 컴퓨터는 0부터 시작하기에 0과 1이 있는 배열 [0,1]에서 0은 0번째, 1은 1번째입니다. 이때 이 배열의 크기는 2이며, 배열의 크기에서 1을 뺀 값인 2-1 = 1은 배열의 가장 마지막 인덱스가 됩니다.
선택된 인덱스가 pairedList의 마지막 요소라면 동작을 수행하며, 이때 마지막으로 추가한 요소가 '취소'입니다.
즉 선택된 요소가 '취소'라면 페어링 되지 않은 기기를 탐색하는 메서드를 호출합니다.
이후 finish() 메서드를 통해 앱을 종료합니다.
b) 그 이외의 인덱스
취소 버튼 이외의 인덱스가 선택되었다면, 해당 인덱스에 해당하는 장치 이름을 devices를 통해 가져온 뒤, toString() 메서드를 통해 문자열 자료형으로 변환합니다. 이후 페어링 된 기기를 연결하는 connectDevice() 메서드에 파라미터로 전달해서 해당 기기를 연결합니다.
이때 paired를 true로 설정한 후 파라미터로 전달합니다. 이는 페어링 여부에 따라 블루투스 장치를 어디서 갖고올지 결정할 때 사용합니다. 만일 페어링된 장치라면 paired를 true로 설정합니다. connectDevice() 메서드에 true가 파라미터로 전달되면 블루투스 장치를 페어링된 장치 목록에서 갖고 옵니다. 만일 페어링되지 않은 장치라면 반대로 시행합니다.
c) bluetoothAdapter.cancelDiscovery()
이 함수는 블루투스 어댑터로 하여금 기기 검색을 종료하도록 하는 메서드입니다.
이 부분은 페어링 되지 않은 기기를 검색할 때 사용되므로, 해당 시간에 설명하겠습니다.
이 메서드를 기기 연결 전에 호출해서 미리 검색을 종료하도록 합니다.
5) setCancelable(false)
setCancelable() 메서드는 디폴트로 true이며, true인 경우 뒤로 가기 버튼이나 다른 화면을 선택했을 때 다이얼로그가 사라집니다.
그러나 이를 방지하기 위해 여기선 false로 설정했습니다.
6) 빌더 생성
builder.create() 메서드를 통해 실제 다이얼로그를 생성합니다. 그러나 단지 생성했다고 해서 다이얼로그가 실행되지는 않습니다.
7) 다이얼로그 실행
show() 함수를 통해 다이얼로그를 실행합니다.
다이얼로그 화면은 다음과 같습니다.
3. 마무리
이번 시간에는 블루투스 기기 검색에 대한 부분과 그중에서도 페어링 된 기기를 검색하는 법에 대해 알아보았습니다. 다음 시간에는 페어링 되지 않은 기기를 검색하는 방법에 대해 설명하겠습니다.
오늘 알려드린 정보가 많은 도움이 되었길 바랍니다.