• Android实践 -- Android蓝牙设置连接


    使用Android Bluetooth APIs将设备通过蓝牙连接并通信,设置蓝牙,查找蓝牙设备,配对蓝牙设备
    连接并传输数据,以下是Android系统提供的蓝牙相关的类和接口

    • BluetoothAdapter
    • BluetoothDevice
    • BluetoothSocket
    • BluetoothServerSocket
    • BluetoothClass
    • BluetoothProfile
    • BluetoothHeadset
    • BluetoothA2dp
    • BluetoothHealth
    • BluetoothHealthCallback
    • BluetoothHealthAppConfiguration
    • BluetoothProfile.ServiceListener

    蓝牙权限

    使用蓝牙功能,需要在AndroidManifest.xml中声明蓝牙相关的权限

      <uses-permission android:name="android.permission.BLUETOOTH"/>
      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

    建立蓝牙

    • 初始化连接

      在通过蓝牙通信之前,需要先确定设备是否支持蓝牙功能,先初始化一个BluetoothAdapter的实例,
      BluetoothAdapter提供了一个静态方法getDefaultAdapter()来获得BluetoothAdapter的实例

      BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
      if (mBluetoothAdapter == null) {
        // 设备不支持蓝牙功能
      }
    • 打开蓝牙
      下一步就是打开蓝牙,调用isEnabled()方法检查蓝牙功能是否已经打开,返回true说明蓝牙已开启,
      返回false说明蓝牙功能未开启,开启蓝牙可以通过发送广播ACTION_REQUEST_ENABLE,也可以通过方法
      enable()直接打开,这两种方法都会有蓝牙权限的提示,选择允许,否则无法打开蓝牙

      if (!mBluetoothAdapter.isEnabled()) {
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
      }
      mBluetoothAdapter.enable();

      在应用中可以设置蓝牙的状态的监听ACTION_STATE_CHANGED广播,当蓝牙的状态的变化时,就会触发这个
      广播,接收到这个广播之后,在intent中可以获得当前蓝牙的状态和前一次的蓝牙的状态

      int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);

      蓝牙的状态值有:

      int STATE_OFF = 10;//蓝牙关闭状态
      int STATE_TURNING_ON = 11;//蓝牙正在打开
      int STATE_ON = 12;//蓝牙打开状态
      int STATE_TURNING_OFF = 13;//蓝牙正在关闭

    查找蓝牙设备

    打开蓝牙之后,下一步就是查找可以使用的蓝牙设备,蓝牙的api中也提供了相关的接口,由于蓝牙的扫描
    是一个耗电的操作,不用时计时取消扫描蓝牙

      mBluetoothAdapter.isDiscovering(); //监测蓝牙是否正在扫描
      mBluetoothAdapter.startDiscovery();//开始扫描
      mBluetoothAdapter.cancelDiscovery();//取消扫描

    为了发现可用的蓝牙的设备,必须在应用中注册ACTION_FOUND的广播,调用方法startDiscovery()如果查找到可用的
    设备会触发这个广播,这个广播中带有EXTRA_DEVICE的设备信息可以通过下面的方法获得设备的信息

      private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
          public void onReceive(Context context, Intent intent) {
              String action = intent.getAction();
              if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                  BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                  Log.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
              }
          }
      };
      IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
      registerReceiver(mReceiver, filter);
    • 查询已经配对的设备列表
      在进行查找之前,可以先获得之前已经配对成功的蓝牙设备的列表,可以调用方法getBondedDevices()获得
      已经配对的蓝牙设备列表

      Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
      if (pairedDevices.size() > 0) {
      for (BluetoothDevice device : pairedDevices) {
          //可以获得已经配对的蓝牙的名称和地址
          Log.e("tag","device name: "+device.getName()+" address: "+device.getAddress());
      }
      }
    • 是其他设备可见
      上面讲的都是发现其他的蓝牙设备,也可以设置设备本身是否对其他设备可见,通过发送ACTION_REQUEST_DISCOVERABLE
      的广播,会调用系统的方法,还可以设置多长时间内是可见的,在intent中设置EXTRA_DISCOVERABLE_DURATION,最大值是
      3600s,超过3600s会设置为120s,点击允许会回调onActivityResult()方法

      //设置设备在300s内是可见的
      Intent discoverableIntent = new
      Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
      discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
      startActivity(discoverableIntent);

      如果没有打开蓝牙,执行上面的操作会自动打开蓝牙

      可以通过监听ACTION_SCAN_MODE_CHANGED广播,可以在intent中根据EXTRA_SCAN_MODE的参数获得当前设备的SCAN MODE
      有一些几种模式

      int SCAN_MODE_NONE = 20;//这个模式不能被发现也不能连接
      int SCAN_MODE_CONNECTABLE = 21;//这个模式不能被扫描到,但是可以连接
      int SCAN_MODE_CONNECTABLE_DISCOVERABLE = 23;//这个模式可以被发现,也能被连接

    蓝牙的连接

    • Server 端
      通过BluetoothAdapterlistenUsingRfcommWithServiceRecord(String, UUID)方法获得BluetoothServerSocket对象
      的实例,然后socket就会通过accept()监听客户端的连接的状态

      private class AcceptThread extends Thread {
        private final BluetoothServerSocket mmServerSocket;
        public AcceptThread() {
            BluetoothServerSocket tmp = null;
            try {
                tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
            } catch (IOException e) { }
            mmServerSocket = tmp;
        }
      
        public void run() {
            BluetoothSocket socket = null;
            // 在后台一直监听客户端的请求
            while (true) {
                try {
                    socket = mmServerSocket.accept();
                } catch (IOException e) {
                    break;
                }
                if (socket != null) {
                    mmServerSocket.close();
                    break;
                }
            }
        }
        public void cancel() {
            try {
                mmServerSocket.close();
            } catch (IOException e) { }
        }
      }
    • Client 端
      使用BluetoothDevicecreateRfcommSocketToServiceRecord(UUID)方法获得BluetoothSocket对象的实例
      然后调用connect()方法,这时server端会监听到这个请求,之后就建立连接,然后就可以进行通信了

      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(MY_UUID);
          } catch (IOException e) { }
          mmSocket = tmp;
      }
      
      public void run() {
          mBluetoothAdapter.cancelDiscovery();
      
          try {
              mmSocket.connect();
          } catch (IOException connectException) {
              try {
                  mmSocket.close();
              } catch (IOException closeException) { }
              return;
          }
      }
      public void cancel() {
          try {
              mmSocket.close();
          } catch (IOException e) { }
      }
      }

    连接的监听

    可以通过注册广播监听蓝牙设备连接的状态变化,广播BluetoothDevice.ACTION_BOND_STATE_CHANGED,监听到这个广播之后,可以
    在intent中获得连接的状态

      int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);

    设备连接的状态值

      int BOND_NONE = 10;//没有连接  
      int BOND_BONDING = 11;//正在连接  
      int BOND_BONDED = 12;//已经建立连接
  • 相关阅读:
    质量属性论文
    四月份-读书笔记 构建之法
    基于二元模型的拼音输入法
    融云单聊
    Gogs私有git仓库 + Drone构建CI/CD
    仿jq ajax封装支付宝小程序request.js
    Electron 和 Angular 构建桌面应用程序
    css多行溢出省略号
    package-lock和package.json
    控制窗体的小程序
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6627314.html
Copyright © 2020-2023  润新知