블루투스 기반 소켓 통신 예제
22 Apr 2017 | Android 블루투스 네트워크안드로이드에서 블루투스(Bluetooth)를 이용하여 간단하게 단말간 통신할 수 있는 코드를 포스팅해봅니다.
단말 2개가 필요하며, 한 쪽 단말은 서버, 한 쪽 단말은 클라이언트가 됩니다. 또한, 두 단말간의 페어링(Pairing) 단계는 이미 되었다고 가정하고 건너뛰도록 하겠습니다.
권한(Permission) 추가
블루투스 통신을 사용하기 위해서는 아래 두 권한이 필요합니다. AndroidManifest.xml
파일에 추가해주시면 됩니다.
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" />
상수값 설정
public class SnowConstant { public static final UUID BLUETOOTH_UUID_SECURE = UUID.fromString( "fa87c0d0-afac-11de-8a39-0800200c9a66" ); public static final UUID BLUETOOTH_UUID_INSECURE = UUID.fromString( "8ce255c0-200a-11e0-ac64-0800200c9a66" ); }
서버
fragment_btserver.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/start_server" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Start Server" /> <Button android:id="@+id/stop_server" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Stop Server" /> <Button android:id="@+id/send_welcome" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Welcome Message" /> <TextView android:id="@+id/logview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
BTServerFragment.java
public class BTServerFragment extends Fragment { Handler handler = new Handler(); TextView logView; StringBuilder sbLog = new StringBuilder(); BluetoothServer btServer = new BluetoothServer(); public BTServerFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_btserver, container, false); logView = (TextView) view.findViewById(R.id.logview); btServer.setOnEventLogListener(new OnEventLogListener() { @Override public void onLog(String message) { log(message); } }); view.findViewById(R.id.start_server).setOnClickListener(mOnClickListener); view.findViewById(R.id.stop_server).setOnClickListener(mOnClickListener); view.findViewById(R.id.send_welcome).setOnClickListener(mOnClickListener); return view; } private View.OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.start_server: btServer.startServer(); break; case R.id.stop_server: btServer.stopServer(); break; case R.id.send_welcome: btServer.sendWelcome(); break; } } }; void log(String message) { sbLog.append(message + "\n"); if (logView != null) { handler.post(new Runnable() { @Override public void run() { logView.setText(sbLog.toString()); } }); } Log.i("", "[snowdeer] " + message); } }
BluetoothServer.java
public class BluetoothServer { BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothServerSocket acceptSocket; AcceptThread acceptThread; DataInputStream is = null; DataOutputStream os = null; public interface OnEventLogListener { void onLog(String message); } OnEventLogListener mOnEventLogListener = null; public void setOnEventLogListener(OnEventLogListener listener) { mOnEventLogListener = listener; } void printLog(String message) { if (mOnEventLogListener != null) { mOnEventLogListener.onLog(message); } } public void startServer() { stopServer(); printLog("Start Server."); acceptThread = new AcceptThread(); acceptThread.start(); } public void stopServer() { if (acceptThread == null) { return; } try { acceptThread.stopThread(); acceptThread.join(1000); acceptThread.interrupt(); } catch (Exception e) { e.printStackTrace(); } printLog("Stop Server."); } class AcceptThread extends Thread { boolean isRunning = false; AcceptThread() { try { acceptSocket = null; acceptSocket = btAdapter.listenUsingRfcommWithServiceRecord("SnowDeerBluetoothSample", SnowConstant.BLUETOOTH_UUID_INSECURE); } catch (Exception e) { e.printStackTrace(); } } public void run() { BluetoothSocket socket; isRunning = true; while (isRunning) { try { printLog("Waiting clients..."); socket = acceptSocket.accept(); } catch (Exception e) { e.printStackTrace(); break; } if (socket != null) { printLog("Client is connected."); CommunicationThread commThread = new CommunicationThread(socket); commThread.start(); } } } public void stopThread() { isRunning = false; try { acceptSocket.close(); } catch (Exception e) { e.printStackTrace(); } } } class CommunicationThread extends Thread { final BluetoothSocket socket; boolean isRunning = false; CommunicationThread(BluetoothSocket socket) { this.socket = socket; } public void run() { isRunning = true; try { is = new DataInputStream(socket.getInputStream()); os = new DataOutputStream(socket.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } while (isRunning) { try { String message = is.readUTF(); printLog(message); } catch (Exception e) { e.printStackTrace(); } } } public void stopThread() { isRunning = false; try { is.close(); os.close(); } catch (Exception e) { e.printStackTrace(); } } } public void sendWelcome() { if (os == null) { return; } try { os.writeUTF("Welcome"); os.flush(); } catch (Exception e) { e.printStackTrace(); } } }
클라이언트
fragment_btclient.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/search_devices" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Search Devices" /> <Button android:id="@+id/connect_to_server" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Connect to Server" /> <Button android:id="@+id/disconnect_from_server" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Disconnect from Server" /> <Button android:id="@+id/send_hello" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Hello Message" /> <TextView android:id="@+id/logview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
BTClientFragment.java
public class BTClientFragment extends Fragment { Handler handler = new Handler(); TextView logView; StringBuilder sbLog = new StringBuilder(); BluetoothClient btClient = new BluetoothClient(); public BTClientFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_btclient, container, false); logView = (TextView) view.findViewById(R.id.logview); btClient.setOnEventLogListener(new OnEventLogListener() { @Override public void onLog(String message) { log(message); } }); view.findViewById(R.id.search_devices).setOnClickListener(mOnClickListener); view.findViewById(R.id.connect_to_server).setOnClickListener(mOnClickListener); view.findViewById(R.id.disconnect_from_server).setOnClickListener(mOnClickListener); view.findViewById(R.id.send_hello).setOnClickListener(mOnClickListener); return view; } private View.OnClickListener mOnClickListener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.search_devices: btClient.searchPairedDevice(); break; case R.id.connect_to_server: btClient.connectToServer(); break; case R.id.disconnect_from_server: btClient.disconnectFromServer(); break; case R.id.send_hello: btClient.sendHello(); break; } } }; void log(String message) { sbLog.append(message + "\n"); if (logView != null) { handler.post(new Runnable() { @Override public void run() { logView.setText(sbLog.toString()); } }); } Log.i("", "[snowdeer] " + message); } }
BluetoothClient.java
public class BluetoothClient { BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); BluetoothDevice mTargetDevice = null; DataInputStream is = null; DataOutputStream os = null; ClientThread clientThread; public interface OnEventLogListener { void onLog(String message); } OnEventLogListener mOnEventLogListener = null; public void setOnEventLogListener(OnEventLogListener listener) { mOnEventLogListener = listener; } void printLog(String message) { if (mOnEventLogListener != null) { mOnEventLogListener.onLog(message); } } public void searchPairedDevice() { Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices(); printLog("paired Devices count : " + pairedDevices.size()); if (pairedDevices.size() > 0) { for (BluetoothDevice deivce : pairedDevices) { printLog(deivce.getName() + " / " + deivce.getAddress()); mTargetDevice = deivce; printLog(deivce.getName() + "(" + deivce.getAddress() + ") is found !!!"); } } } public void connectToServer() { disconnectFromServer(); if (mTargetDevice == null) { return; } printLog("Connect to Server."); clientThread = new ClientThread(mTargetDevice); clientThread.start(); } public void disconnectFromServer() { if (clientThread == null) { return; } try { clientThread.stopThread(); clientThread.join(1000); clientThread.interrupt(); } catch (Exception e) { e.printStackTrace(); } printLog("Disconnect from Server."); } class ClientThread extends Thread { BluetoothSocket socket; BluetoothDevice mDevice; ClientThread(BluetoothDevice device) { try { mDevice = device; //socket = null; socket = device.createRfcommSocketToServiceRecord(SnowConstant.BLUETOOTH_UUID_INSECURE); } catch (Exception e) { e.printStackTrace(); } } public void run() { btAdapter.cancelDiscovery(); while (true) { try { printLog("try to connect to Server..."); socket.connect(); } catch (Exception e) { e.printStackTrace(); try { socket.close(); } catch (Exception ex) { ex.printStackTrace(); } break; } if (socket != null) { printLog("Connected !!!"); try { is = new DataInputStream(socket.getInputStream()); os = new DataOutputStream(socket.getOutputStream()); } catch (Exception e) { e.printStackTrace(); } while (true) { try { String message = is.readUTF(); printLog(message); } catch (Exception e) { e.printStackTrace(); } } } try { sleep(1000); } catch (Exception e) { e.printStackTrace(); } } } public void stopThread() { try { socket.close(); is.close(); os.close(); } catch (Exception e) { e.printStackTrace(); } } } public void sendHello() { if (os == null) { return; } try { os.writeUTF("Hello"); os.flush(); } catch (Exception e) { e.printStackTrace(); } } }