안드로이드 스튜디오에서 블루투스 기능을 구현하는 데 도움 요청드립니다
글쓴이: plusultra179 / 작성시간: 일, 2019/11/03 - 10:19오전
안드로이드 스튜디오를 공부하면서 블루투스 구현을 시도해보고 있습니다.
블루투스 api를 사용하여 블루투스 켜기/끄기, 페어링된 리스트 보여주기, 페어링된 기기 연결하기까지
구현하기 위한 코드입니다.
다른 기능은 되는데 기기 연결 부분이 문제가 있는 것 같습니다.
스레드를 서버, 클라이언트 양방향으로 사용하려고 하고 블루투스가 켜지면 서버 스레드가 생성됩니다.
페어링된 기기 리스트에서 기기를 선택하면 클라이언트 스레드가 생성되고 연결을 시도하는 게 의도인데
실제 디바이스에서 실행해 보니 클라이언트 측의 기기에서 앱이 꺼지는 현상이 발생합니다.
제가 안드로이드의 스레드 원리를 부정확하게 알고 쓴 걸로 예상하는데 힌트 주시면 정말 감사하겠습니다.
(UUID는 제가 임의로 UUID String을 할당해서 했었는데 이게 문제인가 싶어 00001101-0000-1000-8000-00805F9B34FB로 바꿔보기도 하였으나 문제는 계속 발생했습니다.)
안드로이드 실력자분들 도움 부탁드립니다.
package com.practice.bluetoothmodule; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.view.View; 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.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.UUID; import java.util.concurrent.ExecutionException; public class MainActivity extends AppCompatActivity { TextView bthStatus; Button bthOn; Button bthOff; Button bthCon; BluetoothAdapter bthAdapter; Set<BluetoothDevice> pairedDevices; List<String> listofPairedDevices; private String btAddress=null; BluetoothDevice bthDevice; AcceptThread acceptThread; ConnectThread connectThread; private Handler mHandler = null; final static int BT_REQUEST_ENABLE=1; final static UUID BT_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bthStatus = (TextView)findViewById(R.id.text_check); bthOn = (Button)findViewById(R.id.bth_on); bthOff=(Button)findViewById(R.id.bth_off); bthCon=(Button)findViewById(R.id.dev_con); bthAdapter=BluetoothAdapter.getDefaultAdapter(); bthOn.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View view){ bluetoothOn(); } }); bthOff.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View view){ bluetoothOff(); } }); bthCon.setOnClickListener(new Button.OnClickListener(){ @Override public void onClick(View view){ listPairedDevices(); } }); } @Override public void onStart(){ super.onStart(); } @Override public void onDestroy(){ super.onDestroy(); if(acceptThread != null){ acceptThread.cancel(); acceptThread=null; } if(connectThread != null){ connectThread.cancel(); connectThread=null; } } void bluetoothOn(){ if(bthAdapter == null){ Toast.makeText(getApplicationContext(),"블루투스를 지원하지 않는 기기입니다",Toast.LENGTH_SHORT).show(); } else{ if(bthAdapter.isEnabled()){ Toast.makeText(getApplicationContext(),"블루투스가 이미 활성화된 상태입니다",Toast.LENGTH_SHORT).show(); } else{ Toast.makeText(getApplicationContext(),"블루투스가 활성화 되어 있지 않습니다",Toast.LENGTH_SHORT).show(); Intent intentBthEnable = new Intent(bthAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(intentBthEnable,BT_REQUEST_ENABLE); } } } void bluetoothOff(){ if(bthAdapter.isEnabled()){ bthAdapter.disable(); Toast.makeText(getApplicationContext(),"블루투스가 비활성화 되었습니다.",Toast.LENGTH_SHORT).show(); bthStatus.setText("비활성화"); } else{ Toast.makeText(getApplicationContext(),"블루투스가 이미 비활성화 상태입니다",Toast.LENGTH_SHORT).show(); } } @Override protected void onActivityResult(int requestCode,int resultCode,Intent data){ switch(requestCode){ case BT_REQUEST_ENABLE: if(resultCode == RESULT_OK){ Toast.makeText(getApplicationContext(),"블루투스 활성화",Toast.LENGTH_LONG).show(); bthStatus.setText("활성화"); start(); } else if(resultCode == RESULT_CANCELED){ Toast.makeText(getApplicationContext(),"취소",Toast.LENGTH_LONG).show(); bthStatus.setText("비활성화"); } break; } super.onActivityResult(requestCode,resultCode,data); } void listPairedDevices(){ if(bthAdapter.isEnabled()){ pairedDevices = bthAdapter.getBondedDevices(); if(pairedDevices.size()>0){ AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("장치 선택"); listofPairedDevices = new ArrayList(); for(BluetoothDevice device: pairedDevices){ listofPairedDevices.add(device.getName()); } final CharSequence[] items= listofPairedDevices.toArray(new CharSequence[ofPairedDevices.size()]); listofPairedDevices.toArray(new CharSequence[ofPairedDevices.size()]); builder.setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int item) { connectSelectedDevice(items[item].toString()); } }); AlertDialog alert=builder.create(); alert.show(); } else{ Toast.makeText(getApplicationContext(),"페어링된 장치가 없습니다",Toast.LENGTH_LONG).show(); } } else{ Toast.makeText(getApplicationContext(),"블루투스가 비활성화 되어 있습니다.",Toast.LENGTH_LONG).show(); } } void connectSelectedDevice(String selectedDeviceName){ for(BluetoothDevice tempDevice: pairedDevices){ if(selectedDeviceName.equals(tempDevice.getName())){ bthDevice=tempDevice; btAddress=bthDevice.getAddress(); break; } } connect(bthDevice); //Toast.makeText(getApplicationContext(),"연결 시도"+bthDevice.getName(),Toast.LENGTH_LONG).show(); } public synchronized void start(){ acceptThread = new AcceptThread(); acceptThread.start(); } public synchronized void connect(BluetoothDevice device){ connectThread=new ConnectThread(device); connectThread.start(); } private class AcceptThread extends Thread{ private final BluetoothServerSocket mmServerSocket; public AcceptThread(){ BluetoothServerSocket tmp=null; try{ tmp=bthAdapter.listenUsingRfcommWithServiceRecord("Listen",BT_UUID); Toast.makeText(getApplicationContext(),"서버 열림",Toast.LENGTH_LONG).show(); }catch(IOException e){ Toast.makeText(getApplicationContext(),"서버 안열림",Toast.LENGTH_LONG).show(); } mmServerSocket=tmp; } public void run(){ BluetoothSocket socket=null; while(true){ try{ socket=mmServerSocket.accept(); } catch(IOException e){ break; } if(socket != null){ Toast.makeText(getApplicationContext(),"연결됨",Toast.LENGTH_SHORT).show(); try{ sleep(3000); } catch (Exception e){} } } } public void cancel(){ try{ mmServerSocket.close(); } catch(IOException e){ e.printStackTrace(); } } } private class ConnectThread extends Thread{ private final BluetoothSocket mmSocket; private final BluetoothDevice mmDevice; public ConnectThread(BluetoothDevice device){ BluetoothSocket tmp=null; mmDevice=device; try{ tmp=device.createRfcommSocketToServiceRecord(BT_UUID); //Toast.makeText(getApplicationContext(),"클라 초기화 됨.",Toast.LENGTH_LONG).show(); }catch (IOException e){ //Toast.makeText(getApplicationContext(),"클라 초기화 실패.",Toast.LENGTH_LONG).show(); } mmSocket=tmp; //Toast.makeText(getApplicationContext(),"클라 초기화",Toast.LENGTH_LONG).show(); } public void run() { try { bthAdapter.cancelDiscovery(); mmSocket.connect(); Toast.makeText(getApplicationContext(), "클라이언트 연결", Toast.LENGTH_LONG).show(); } catch (IOException e) { Toast.makeText(getApplicationContext(), "연결실패", Toast.LENGTH_LONG).show(); } } public void cancel(){ try{ mmSocket.close(); } catch (IOException e){ e.printStackTrace(); } } } }
Forums:
댓글 달기