블루투스 기반 소켓 통신 예제
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();
}
}
}



