본문 바로가기

졸업 프로젝트

[React native - Expo] Bluetooth-Classic (2) 데이터 전송 및 수신

데이터 전송

자꾸 이런 오류가 뜬다... 싸늘하다...

buffer도 해보고 arrayBuffer도 해보고

 

아 근데 진짜 오랫동안 붙잡고있었는데..

 

- Bluetooth.js

try {
      // 디바이스 연결 시도
      const connectionStatus = await connectToDevice(id);
      console.log("연결 상태:", connectionStatus);

      if (connectionStatus) {
        const sendResult = await sendData(id, cardId);
        console.log("전송 결과:", sendResult);
        
      ---
    }

 

- UseBluetoothClassic.js

  async function sendData(deviceId, cardId) {
    try {
      const dataToSend = String(cardId);
      const result = await BluetoothClassic.writeToDevice(deviceId, dataToSend); // 블루투스 연결할 디바이스, 전송할 데이터
      console.log('전송 성공:', result);
      return result;
    } catch (error) {
      console.log('전송 오류:', error.message);
      return false;
    }
  }

 

wirteToDevice에 블루투스 연결된 디바이스와 전송할 데이터를 같이 보내줬다.

 

불친절한 공식문서와 레퍼런스가 없어서 여러가지 다 해보다가 결국 해냈지 모야~


데이터 수신

async function receiveData(deviceId) {
    try {
      const connectedDevice = await connectToDevice(deviceId); // 데이터를 수신한 디바이스에 연결
      if (connectedDevice) {
        const receivedData = await connectedDevice.read(); // cardId 읽기

        // Buffer에서 문자열로 변환
        const cardId = receivedData.toString();
        console.log("받은 카드 ID:", cardId);

        // 상대카드 저장 API 요청
        if (cardId) {
          const response = await axios.post(`${baseUrl}/card/save?cardId=${cardId}`, {}, {
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${token}`,
            },
          });

          if (response.status === 200) {
            if (response.data.added) {
              console.log("카드 ID 저장 성공:", response.data.message); // "카드가 저장되었습니다" 
            } else {
              console.log("카드 ID 저장 실패:", response.data.message); // "이미 저장된 카드입니다"
            }
          } else {
            console.log("카드 ID 저장 실패:", response.data);
          }
        }
        return cardId;
      } else {
        console.log("receiveData - 연결된 디바이스가 없습니다.");
      }
    } catch (error) {
      console.log("receiveData - 데이터 읽기 오류:", error);
    }
  }

 

수신하는 데이터가 단일 데이터라면 read()가 적합하고,

readFromDevice()는 데이터를 여러 번에 걸쳐 나누어 받는 경우 사용한다.

 

나는 cardId 인 정수 하나만 보낼 거니까 read() 사용한다.


+) 최종 소스코드 bluetooth.js

function Step2Screen({ route }) {
  const { permissionGranted = false, cardId } = route.params || {};

  const [recipients, setRecipients] = useState([]);
  const [recipientStatuses, setRecipientStatuses] = useState({});
  const { scanForPeripherals, connectToDevice, sendData, receiveData, allDevices } = useBluetoothClassic();
  const [isScanning, setIsScanning] = useState(false);
  const [receivedData, setReceivedData] = useState([]);
  const [isModalVisible, setIsModalVisible] = useState(false);

  useEffect(() => {
    const startScanning = async () => {
      if (permissionGranted && !isScanning) {
        setIsScanning(true);
        await scanForPeripherals();
      }
    };
    startScanning();
  }, [permissionGranted, isScanning]);

  useEffect(() => {
    setRecipients(allDevices || []);
  }, [allDevices]);

  const handlePressRecipient = async (deviceId, cardId) => {
    setRecipientStatuses((prevStatuses) => ({
      ...prevStatuses,
      [deviceId]: '요청 중...'
    }));

    try {
      // 디바이스 연결 시도
      const connectionStatus = await connectToDevice(deviceId);
      console.log("연결 상태:", connectionStatus);

      if (connectionStatus) {
        const sendResult = await sendData(deviceId, cardId);
        console.log("전송 결과:", sendResult);

        // 카드 ID 전송 성공
        if (sendResult) {
          setRecipientStatuses((prevStatuses) => ({
            ...prevStatuses,
            [deviceId]: '공유 완료됨'
          }));

          // 받은 데이터를 모달로 설정
          setReceivedData(`기기 ID: ${deviceId} , 카드 ID: ${cardId}`);
        } else {
          setRecipientStatuses((prevStatuses) => ({
            ...prevStatuses,
            [deviceId]: '전송 실패'
          }));
        }
      } else {
        setRecipientStatuses((prevStatuses) => ({
          ...prevStatuses,
          [deviceId]: '연결 실패'
        }));
      }
    } catch (error) {
      console.log('오류 발생:', error.message || error.toString());
      setRecipientStatuses((prevStatuses) => ({
        ...prevStatuses,
        [deviceId]: '오류 발생'
      }));
    }
  }

  // 데이터 수신 시 모달 표시
  useEffect(() => {
    if (receivedData.length > 0) {
      setIsModalVisible(true);
    }
  }, [receivedData]);
  
  return ()
  }