2021년 11월 23일 화요일

블루투스 RFCOMM, read failed. 안드로이드 4.2 이후에서 사용하기

참조 자료 : IOException: read failed, socket might closed - Bluetooth on Android 4.3

java.io.IOException: read failed, socket might closed, read ret: -1
보기만해도 막막한 에러문구다. 블루투스를 PC에서 디버깅할 수도 없고, 핸드폰에 APK를 설치하고 개발자 모드를 키기에는 너무나 귀찮아 검색을 했고, 성과를 얻었다.

public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
                new ParcelUuid(uuid));
    }
 해당 에러는 createRfcommSocketToServiceRecord 함수로 인해 발생하는데, 생성 시 블루투스 RFCOMM 채널이 어떤 이유에서인지는 모르지만 채널번호가 -1로 설정된다. 

 listenUsingRfcommWithServiceRecord에서 이 함수가 사용된다고 하는데, "The system will assign an unused RFCOMM channel to listen on." 라는 주석이 붙어있다. 예상하기로는 채널로 배정될 수 없는 -1로 초기화하고, 배정 시도 후 배정되지 않은 대상들은 -1로 남아있을 것이니 이로 에러를 캐치하기 위함인 듯 하다는 생각이다. 

 그리고,
public BluetoothSocket createRfcommSocket(int channel) throws IOException {
        return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
                null);
    }
 다른 RFCOMM Socket 생성 함수인 createRfcommSocket은 채널 숫자를 받아서 생성을 한다. 그런데, 어째서 이 함수를 왜 발견하지 못한걸까. 
좀 더 정확한 질문은, 이게 왜 숨겨져 있을까 같다.
 그런 이유에서, 이를 우회하는 방법으로 함수를 사용한다.
mBluetoothSocket = (BluetoothSocket) mBluetoothDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(mBluetoothDevice,1);
mBluetoothSocket.connect();

댓글 없음:

댓글 쓰기

[번] Callback 지옥, Promises, 그리고 Async/Await

원문:  https://blog.avenuecode.com/callback-hell-promises-and-async/await  Callbacks와 promises, 그리고 async/await을 쓰는 비동기 자바스크립트는 반환하는데 시간이 소요되는...