마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

아두이노 센서 값을 안드로이드에 받고 싶어서 코드를 따왔는데 오류를 수정이 감이 안 잡히네요ㅠㅠ(코드가 길어서 댓글로 남겼습니다!!)

0 추천
코드가 길어서 댓글로 남기겠습니다ㅠㅠ
크릴리 (120 포인트) 님이 2023년 3월 9일 질문
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_ENABLE_BT = 10; // 블루투스 활성화 상태
    private BluetoothAdapter bluetoothAdapter; // 블루투스 어댑터
    private Set<BluetoothDevice> devices; // 블루투스 디바이스 데이터 셋
    private BluetoothDevice bluetoothDevice; // 블루투스 디바이스
    private BluetoothSocket bluetoothSocket = null; // 블루투스 소켓
    private OutputStream outputStream = null; // 블루투스에 데이터를 출력하기 위한 출력 스트림
    private InputStream inputStream = null; // 블루투스에 데이터를 입력하기 위한 입력 스트림
    private Thread workerThread = null; // 문자열 수신에 사용되는 쓰레드
    private byte[] readBuffer; // 수신 된 문자열을 저장하기 위한 버퍼
    private int readBufferPosition; // 버퍼 내 문자 저장 위치
    private TextView textViewReceive; // 수신 된 데이터를 표시하기 위한 텍스트 뷰
    private EditText editTextSend; // 송신 할 데이터를 작성하기 위한 에딧 텍스트
    private Button buttonSend; // 송신하기 위한 버튼

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textViewReceive = (TextView)findViewById(R.id.textView_receive);
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(bluetoothAdapter == null) { // 디바이스가 블루투스를 지원하지 않을 때
            Toast.makeText(getApplicationContext(), "Bluetooth 미지원 기기입니다.", Toast.LENGTH_SHORT).show();
        }
        else { // 디바이스가 블루투스를 지원 할 때
            if(bluetoothAdapter.isEnabled()) { // 블루투스가 활성화 상태 (기기에 블루투스가 켜져있음)
                selectBluetoothDevice(); // 블루투스 디바이스 선택 함수 호출
            }
            else { // 블루투스가 비 활성화 상태 (기기에 블루투스가 꺼져있음)
                // 블루투스를 활성화 하기 위한 다이얼로그 출력
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                // 선택한 값이 onActivityResult 함수에서 콜백된다.
                startActivityForResult(intent, REQUEST_ENABLE_BT);
                selectBluetoothDevice();
            }
        }
    }
@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case REQUEST_ENABLE_BT :
                if(requestCode == RESULT_OK) { // '사용'을 눌렀을 때
                    selectBluetoothDevice(); // 블루투스 디바이스 선택 함수 호출
                }
                else {
                    Toast.makeText(getApplicationContext(), "Bluetooth 디바이스 취소", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
    public void selectBluetoothDevice() {
        // 이미 페어링 되어있는 블루투스 기기를 찾습니다.
        devices = bluetoothAdapter.getBondedDevices();
        // 페어링 된 디바이스의 크기를 저장
        pariedDeviceCount = devices.size();
        // 페어링 되어있는 장치가 없는 경우
        if(pariedDeviceCount == 0) {
            // 페어링을 하기위한 함수 호출
            Toast.makeText(getApplicationContext(), "먼저 Bluetooth 설정에 들어가 페어링을 진행해 주세요.", Toast.LENGTH_SHORT).show();
        }
        // 페어링 되어있는 장치가 있는 경우
        else {
            // 디바이스를 선택하기 위한 다이얼로그 생성
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("페어링 되어있는 블루투스 디바이스 목록");
            // 페어링 된 각각의 디바이스의 이름과 주소를 저장
            List<String> list = new ArrayList<>();
            // 모든 디바이스의 이름을 리스트에 추가
            for(BluetoothDevice bluetoothDevice : devices) {
                list.add(bluetoothDevice.getName());
            }
            list.add("취소");
            // List를 CharSequence 배열로 변경
            final CharSequence[] charSequences = list.toArray(new CharSequence[list.size()]);
            list.toArray(new CharSequence[list.size()]);
            // 해당 아이템을 눌렀을 때 호출 되는 이벤트 리스너
            builder.setItems(charSequences, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // 해당 디바이스와 연결하는 함수 호출
                    connectDevice(charSequences[which].toString());
                }
            });
            // 뒤로가기 버튼 누를 때 창이 안닫히도록 설정
            builder.setCancelable(false);
            // 다이얼로그 생성
            AlertDialog alertDialog = builder.create();
            alertDialog.show();
        }
    }
    public void connectDevice(String deviceName) {
        // 페어링 된 디바이스들을 모두 탐색
        for(BluetoothDevice tempDevice : devices) {
            // 사용자가 선택한 이름과 같은 디바이스로 설정하고 반복문 종료
            if(deviceName.equals(tempDevice.getName())) {
                bluetoothDevice = tempDevice;
                break;
            }
        }
        // UUID 생성
        UUID uuid = java.util.UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
        // Rfcomm 채널을 통해 블루투스 디바이스와 통신하는 소켓 생성
        try {
            bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
            bluetoothSocket.connect();
            // 데이터 송,수신 스트림을 얻어옵니다.
            outputStream = bluetoothSocket.getOutputStream();
            inputStream = bluetoothSocket.getInputStream();
            // 데이터 수신 함수 호출
            receiveData();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void receiveData() {
        final Handler handler = new Handler();
        // 데이터를 수신하기 위한 버퍼를 생성
        readBufferPosition = 0;
        readBuffer = new byte[1024];
        // 데이터를 수신하기 위한 쓰레드 생성
        workerThread = new Thread(new Runnable() {
            @Override
            public void run() {
                while(Thread.currentThread().isInterrupted()) {
                    try {
                        // 데이터를 수신했는지 확인합니다.
                        int byteAvailable = inputStream.available();
                        // 데이터가 수신 된 경우
                        if(byteAvailable > 0) {
                            // 입력 스트림에서 바이트 단위로 읽어 옵니다.
                            byte[] bytes = new byte[byteAvailable];
                            inputStream.read(bytes);
                            // 입력 스트림 바이트를 한 바이트씩 읽어 옵니다.
                            for(int i = 0; i < byteAvailable; i++) {
                                byte tempByte = bytes[i];
                                // 개행문자를 기준으로 받음(한줄)
                                if(tempByte == '\n') {
                                    // readBuffer 배열을 encodedBytes로 복사
                                    byte[] encodedBytes = new byte[readBufferPosition];
                                    System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length);
                                    // 인코딩 된 바이트 배열을 문자열로 변환
                                    final String text = new String(encodedBytes, "US-ASCII");
                                    readBufferPosition = 0;
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            // 텍스트 뷰에 출력
                                            textViewReceive.append(text + "\n");
                                        }
                                    });
                                } // 개행 문자가 아닐 경우
                                else {
                                    readBuffer[readBufferPosition++] = tempByte;
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        // 1초마다 받아옴
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        workerThread.start();
    }
}

1개의 답변

0 추천

chatGPT 한테 샘플코드를 요구했더니 아래 코드를 주네요. 참고하세요.

 

import java.io.IOException;
import java.util.UUID;

import javax.bluetooth.BluetoothDevice;
import javax.bluetooth.BluetoothDiscoveryAgent;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;

public class BluetoothCommunicator {
    private UUID uuid;
    private RemoteDevice device;
    private boolean isConnected;

    public BluetoothCommunicator(UUID uuid) {
        this.uuid = uuid;
        this.device = null;
        this.isConnected = false;
    }

    public boolean connectToDevice(String deviceName) {
        try {
            LocalDevice localDevice = LocalDevice.getLocalDevice();
            BluetoothDiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent();

            // Start device discovery to find the target device
            Object inquiryCompletedEvent = new Object();
            DiscoveryListener listener = new DiscoveryListener() {
                public void deviceDiscovered(RemoteDevice device, DeviceClass deviceClass) {
                    try {
                        String name = device.getFriendlyName(false);
                        if (name.equals(deviceName)) {
                            BluetoothCommunicator.this.device = device;
                            discoveryAgent.cancelInquiry(this);
                            synchronized (inquiryCompletedEvent) {
                                inquiryCompletedEvent.notifyAll();
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                public void inquiryCompleted(int discType) {
                    synchronized (inquiryCompletedEvent) {
                        inquiryCompletedEvent.notifyAll();
                    }
                }

                public void serviceSearchCompleted(int transID, int respCode) {
                }

                public void servicesDiscovered(int transID, ServiceRecord[] serviceRecords) {
                }
            };

            synchronized (inquiryCompletedEvent) {
                discoveryAgent.startInquiry(DiscoveryAgent.GIAC, listener);
                inquiryCompletedEvent.wait();
            }

            if (device == null) {
                System.out.println("Device not found.");
                return false;
            }

            // Pair with the device
            if (!device.isAuthenticated()) {
                boolean isAuthenticated = device.authenticate();
                if (!isAuthenticated) {
                    System.out.println("Could not authenticate with device.");
                    return false;
                }
            }

            // Connect to the device
            if (!isConnected) {
                BluetoothCommunicatorStreamHandler streamHandler = new BluetoothCommunicatorStreamHandler(device, uuid);
                isConnected = streamHandler.connect();
            }

            return isConnected;

        } catch (BluetoothStateException e) {
            e.printStackTrace();
            return false;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
    }

    public boolean send(String message) {
        if (!isConnected) {
            System.out.println("Not connected to a device.");
            return false;
        }

        BluetoothCommunicatorStreamHandler streamHandler = new BluetoothCommunicatorStreamHandler(device, uuid);
        return streamHandler.send(message);
    }

    public String receive() {
        if (!isConnected) {
            System.out.println("Not connected to a device.");
            return null;
        }

        BluetoothCommunicatorStreamHandler streamHandler = new BluetoothCommunicatorStreamHandler(device, uuid);
        return streamHandler.receive();
    }

    public boolean disconnect() {
        if (!isConnected) {
            System.out.println("Not connected to a device.");
            return false;
        }

        BluetoothCommunicatorStreamHandler streamHandler = new BluetoothCommunicatorStreamHandler(device, uuid);
        boolean isDisconnected = streamHandler.disconnect();
        if (isDisconnected) {
            isConnected = false;
        }
        return isDisconnected;
    }
}


 

spark (223,720 포인트) 님이 2023년 3월 10일 답변
선생님 ㅠㅠ 이 코드를 메인에 넣어야 하나요,,,?
...