簡単なBluetooth通信

18853 ワード

個人ブログ:haichenyi.com.ご注目ありがとうございます
以前、会社はスマートホームタイプをしていましたが、その中でスマートたんすプロジェクトを作りました.たんすと通信するのはBluetooth通信です.いくつかの操作は簡単なスイッチ命令で、Bluetooth通信はsocketと似ています.
ステップ
  • インベントリファイル登録権限
  • Bluetoothサービス(インベントリファイルに静的に登録するサービスを覚えている)
  • を開始する.
  • Bluetoothブロードキャスト(BluetoothサービスにおけるBluetoothブロードキャストの動的登録)
  • を登録する.
  • 検索、バインド、完了
  • appを終了し、サービスを停止し、BluetoothサービスのonDestoryメソッドでBluetoothブロードキャスト
  • の登録を解除する.
    説明を書きたくなくて、ただコードを貼りたいだけです
    ステップ1:登録権限
        
        <uses-permission android:name="android.permission.BLUETOOTH"/>
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    ステップ2、ステップ3、ステップ5:Bluetoothサービスを起動し、Bluetooth放送を登録し、サービスを停止する
    
    /**
     * Author:    .
     * Date: 2018/1/4
     * Desc:
     */
    public class BluetoothService extends Service {
      //       
      private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
      private BluetoothReceiver mReceiver;
    
      @Override
      public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);
        if (mBluetoothAdapter != null) {
          mReceiver = new BluetoothReceiver().setBluetoothAdapter(mBluetoothAdapter);
          //           
          IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
          registerReceiver(mReceiver, filter);
          //            
          IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
          registerReceiver(mReceiver, filter2);
          startLinkBluetooth();
        }
      }
    
      @Nullable
      @Override
      public IBinder onBind(Intent intent) {
        return null;
      }
    
      /**
       *         .
       */
      private void startLinkBluetooth() {
        if (null != mBluetoothAdapter) {
          //        
          if (!mBluetoothAdapter.isEnabled()) {
            //         
            mBluetoothAdapter.enable();
          }
          mBluetoothAdapter.startDiscovery();
          Log.v(Constants.HTTP_WZ, "    ");
        }
      }
    
      @Subscribe
      @SuppressWarnings("unused")
      public void handleMsg(BluetoothInfo bluetoothInfo) {
        if (bluetoothInfo.isLink) {
          startLinkBluetooth();
        }
      }
    
      public static class BluetoothInfo {
        private boolean isLink = false;
    
        public BluetoothInfo setLink(boolean link) {
          this.isLink = link;
          return this;
        }
      }
    
      @Override
      public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        if (mReceiver != null) {
          mReceiver.unRegister();
          unregisterReceiver(mReceiver);
        }
      }
    }
    これが私のBluetoothサービスクラスです.このクラスの論理はどうやって行きますか?
  • EventBusのものは言わない
  • まずBluetoothアダプタ
  • を取得する.
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  • Bluetoothブロードキャストを初期化し、Bluetoothブロードキャスト
  • を登録する.
    if (mBluetoothAdapter != null) {
          mReceiver = new BluetoothReceiver().setBluetoothAdapter(mBluetoothAdapter);
          //           
          IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
          registerReceiver(mReceiver, filter);
          //            
          IntentFilter filter2 = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
          registerReceiver(mReceiver, filter2);
          startLinkBluetooth();
        }
  • Bluetoothデバイス
  • への接続の準備を開始する.
    /**
       *         .
       */
      private void startLinkBluetooth() {
        if (null != mBluetoothAdapter) {
          //        
          if (!mBluetoothAdapter.isEnabled()) {
            //         
            mBluetoothAdapter.enable();
          }
          mBluetoothAdapter.startDiscovery();
          Log.v(Constants.HTTP_WZ, "    ");
        }
      }
  • の4ステップのBluetoothスキャンが完了しました.ここで私が言いたいのは、サービスのonDestoryメソッドでは、サービス
  • を停止することを覚えています.
    @Override
      public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        if (mReceiver != null) {
          mReceiver.unRegister();
          unregisterReceiver(mReceiver);
        }
      }
  • さらにリストファイルにBluetoothサービス
  • を静的に登録する.
    <service android:name=".service.BluetoothService"/>
  • サービスを開始する方法、私は非バインドの方法を使って、同じように、サービスを停止することを覚えています.
  • Intent bluetoothService = new Intent(this, BluetoothService.class);
    startService(bluetoothService);//      
    stopService(bluetoothService);
    @Nullable
      @Override
      public IBinder onBind(Intent intent) {
      //     ,    null
        return null;
      }
    ステップ4:検索、バインド、検索の完了
    
    /**
     * Author:    .
     * Date: 2018/1/4
     * Desc:       
     */
    public class BluetoothReceiver extends BroadcastReceiver {
      //       
      private static final String WARDROBE_NAME = "WARDROBE";
      //    UUID
      private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
      private BluetoothSocket bluetoothSocket;
      private BluetoothAdapter bluetoothAdapter;
      private InputStream mInputStream;
      private OutputStream outputStream;
      private boolean isRunning = false;
    
      @Override
      public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action != null) {
          if (action.equals(BluetoothDevice.ACTION_FOUND)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Log.v(Constants.HTTP_WZ, device.getName() + device.getAddress());
            if (device.getBondState() == BluetoothDevice.BOND_BONDED
                && device.getName().equals(WARDROBE_NAME)) {
              UUID uuid = UUID.fromString(SPP_UUID);
              try {
                bluetoothSocket = device.createRfcommSocketToServiceRecord(uuid);
                Log.v(Constants.HTTP_WZ, "    ");
                connect();
              } catch (IOException e) {
                e.printStackTrace();
              }
            }
          } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
            if (!EventBus.getDefault().isRegistered(this))
              EventBus.getDefault().register(this);
            Observable.timer(2, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(aLong -> {
                  if (null == bluetoothSocket || !bluetoothSocket.isConnected())
                    ToastUtils.showTipMsg(R.string.no_wardrobe);
                });
          }
        }
      }
    
      private void connect() {
        new Thread(() -> {
          if (bluetoothSocket != null) {
            bluetoothAdapter.cancelDiscovery();
            try {
              bluetoothSocket.connect();
              Observable.just(1)
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(integer -> ToastUtils.showTipMsg(R.string.link_wardrobe));
              Log.v(Constants.HTTP_WZ, "    ");
              mInputStream = bluetoothSocket.getInputStream();
              Log.v(Constants.HTTP_WZ, "mInputSream:" + mInputStream.toString());
              isRunning = true;
              outputStream = bluetoothSocket.getOutputStream();
              Log.v(Constants.HTTP_WZ, "outputStream:" + outputStream.toString());
              BufferedReader br;
              while (isRunning) {
                br = new BufferedReader(new InputStreamReader(mInputStream, "utf-8"));
                String s = br.readLine();
                //acceptReply(s);
                Log.v(Constants.HTTP_WZ, "     :" + s);
              }
            } catch (IOException e) {
              e.printStackTrace();
              try {
                if (mInputStream != null) {
                  mInputStream.close();
                  Log.v(Constants.HTTP_WZ, "mInputSream.close()");
                }
                if (outputStream != null) {
                  outputStream.close();
                  Log.v(Constants.HTTP_WZ, "outputStream.close()");
                }
                if (bluetoothSocket != null) {
                  bluetoothSocket.close();
                  Log.v(Constants.HTTP_WZ, "socket.close()");
                  bluetoothSocket = null;
                }
                isRunning = false;
              } catch (Exception e2) {
                // TODO: handle exception
              }
            }
          }
        }).start();
      }
    
      public BluetoothReceiver setBluetoothAdapter(BluetoothAdapter adapter) {
        this.bluetoothAdapter = adapter;
        return this;
      }
    
      /**
       *    eventBus.
       */
      public void unRegister() {
        EventBus.getDefault().unregister(this);
      }
    
    }
    これが私のBluetooth放送クラスですが、この論理はどうやって行きますか?
  • 前のサービスに登録されている2つのaction、1つのBluetoothDevice.ACTION_FOUND、もう一つBluetoothAdapter.ACTION_DISCOVERY_FINISHEDは、デバイスを発見したのか、スキャンデバイス
  • が完了したのかをifで判断した.
  • デバイスを発見した後、Bluetooth情報を取得します.ここでは、Bluetooth情報を取得すると、この方法を一度にリストを取得するわけではありません.
  • Bluetoothデバイスを見つけたら接続します.疑似コードの説明:
  • //    UUID       uuid
      private static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    
    //  socket
    BluetoothSocket bluetoothSocket =device.createRfcommSocketToServiceRecord(uuid);
    
    //        ,      。adapter         ,  setBluetoothAdapter      
    bluetoothAdapter.cancelDiscovery();
    
    //  ,        ,         
    bluetoothSocket.connect();
    
    //             
    InputStream mInputStream = bluetoothSocket.getInputStream();
    OutputStream outputStream = bluetoothSocket.getOutputStream();
    
    //    
    private void sendInstruct(String msg) {
        try {
          if (null == bluetoothSocket || !bluetoothSocket.isConnected()) {
            SocketUtils.reLinkBluetooth();
            return;
          }
          Log.v(Constants.HTTP_WZ, "     -->" + msg + BluetoothInstruct.FINISH);
          outputStream.write(msg.getBytes());
          outputStream.flush();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    
    //    ,     ,                
    BufferedReader br;
    while (isRunning) {
                br = new BufferedReader(new InputStreamReader(mInputStream, "utf-8"));
                String s = br.readLine();
                acceptReply(s);
                Log.v(Constants.HTTP_WZ, "     :" + s);
              }
    
    //         
    try {
                if (mInputStream != null) {
                  mInputStream.close();
                  Log.v(Constants.HTTP_WZ, "mInputSream.close()");
                }
                if (outputStream != null) {
                  outputStream.close();
                  Log.v(Constants.HTTP_WZ, "outputStream.close()");
                }
                if (bluetoothSocket != null) {
                  bluetoothSocket.close();
                  Log.v(Constants.HTTP_WZ, "socket.close()");
                  bluetoothSocket = null;
                }
                isRunning = false;
              } catch (Exception e2) {
                // TODO: handle exception
              }