Android系统蓝牙的使用

概述

本文基于 gitee 项目 administer/AndroidBluetooth。 实现了经典蓝牙的查找、配对、连接,低功耗蓝牙的查找、连接、通信。

1.Android系统蓝牙

1.1 Android系统支持经典蓝牙和低功耗蓝牙:

  • Classic Bluetooth(经典蓝牙)。 用于大量的通信时,例如:音频、短信和电话。
  • Bluetooth Low Energy(低功耗蓝牙)。 用于低频的通信时,例如:心率监测器、无线键盘,要求Android4.3及更高版本。

1.2 蓝牙堆栈的常规结构

蓝牙应用通过 Binder 与蓝牙进程进行通信。蓝牙进程使用 JNI 与蓝牙堆栈通信,并向开发者提供对各种蓝牙配置文件的访问权限。如下图:

2.经典蓝牙

2.1 申请蓝牙权限

java 复制代码
    <!--蓝牙 API30及以下需要申请4个权限,API31及以上时权限列表将不会列出这些权限-->
    <!--蓝牙 连接、通信-->
    <uses-permission
        android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <!--蓝牙 扫描、设置-->
    <uses-permission
        android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />
    <!--蓝牙 API30及以下需要定位权限 -->
    <uses-permission
        android:name="android.permission.ACCESS_COARSE_LOCATION"
        android:maxSdkVersion="30" />
    <uses-permission
        android:name="android.permission.ACCESS_FINE_LOCATION"
        android:maxSdkVersion="30" />

    <!--蓝牙 API31及以上需要申请3个权限-->
    <!--蓝牙 扫描,可不申请定位权限-->
    <uses-permission
        android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s" />
    <!--蓝牙 广播,被发现-->
    <!--<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />-->
    <!--蓝牙 连接、通信-->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

2.2 设置蓝牙

java 复制代码
//蓝牙适配器
BluetoothManager bluetoothManager = context.getSystemService(BluetoothManager.class);
BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
//注册广播接收者
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
mContext.registerReceiver(receiver, intentFilter);
//广播接收者
private final BroadcastReceiver receiver = 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);
      } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//扫描结束
      } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//配对状态变化
         BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
         int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
      } else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {//连接状态变化
         BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
         int connectState = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.ERROR);
      }
   }
};

2.3 查找蓝牙设备

java 复制代码
//查询已配对设备
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
//扫描 大概12s,扫描中不能立即重新扫描
if (!bluetoothAdapter.isDiscovering()) {
   bluetoothAdapter.startDiscovery();
}

2.3 连接蓝牙设备

java 复制代码
public void connectDevice(BluetoothDevice device) {
   if (bluetoothAdapter != null) {//取消扫描
      bluetoothAdapter.cancelDiscovery();
    }
   //已配对的取消配对,配对后自动连接。
   if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
      removeBondDevice(device);//取消配对
      AppExecutors.getInstance().scheduledWork().schedule(() -> {
         device.createBond();//延时配对
      }, 1, TimeUnit.SECONDS);
   } else if (device.getBondState() == BluetoothDevice.BOND_NONE) {
            device.createBond();//配对
   }
}

//判断设备是否连接
public static boolean isDeviceConnected(BluetoothDevice device) {
   boolean isConnected = false;
   try {
      isConnected = (boolean) device.getClass().getMethod("isConnected").invoke(device);
   } catch (Exception e) {
      e.printStackTrace();
   }
   return isConnected;
}

//解绑设备
public static boolean removeBondDevice(BluetoothDevice device) {
   boolean state = false;
   try {
      state = (boolean) device.getClass().getMethod("removeBond").invoke(device);
   } catch (Exception e) {
      e.printStackTrace();
   }
   return state;
}

3.低功耗蓝牙

3.1 查找蓝牙设备

java 复制代码
//扫描一段时间后结束
AppExecutors.getInstance().scheduledWork().schedule(() -> {
   bluetoothAdapter.getBluetoothLeScanner().stopScan(scanCallback);
}, 10, TimeUnit.SECONDS);
bluetoothAdapter.getBluetoothLeScanner().startScan(scanCallback);

3.2 连接蓝牙设备

java 复制代码
//连接
bluetoothGatt = device.connectGatt(mContext, false, gattCallback, BluetoothDevice.TRANSPORT_LE)
//断开连接
bluetoothGatt.disconnect();

3.3 写入数据

java 复制代码
byte[] data;
writeCharacteristic.setValue(data);
bluetoothGatt.writeCharacteristic(writeCharacteristic);

4.官方文档

通信技术-蓝牙概览

通信技术-蓝牙开发

相关推荐
程序员陆业聪2 小时前
从 OpenClaw 到 Android:Harness Engineering 是怎么让 Agent 变得可用的
android
hnlgzb4 小时前
常见的Android Jetpack库会有哪些?这些库中又有哪些常用类的?
android·android jetpack
钛态7 小时前
Flutter 三方库 http_mock_adapter — 赋能鸿蒙应用开发的高效率网络接口 Mock 与自动化测试注入引擎(适配鸿蒙 HarmonyOS Next ohos)
android·网络协议·flutter·http·华为·中间件·harmonyos
王码码20357 小时前
Flutter for OpenHarmony:Flutter 三方库 algoliasearch 毫秒级云端搜索体验(云原生搜索引擎)
android·前端·git·flutter·搜索引擎·云原生·harmonyos
左手厨刀右手茼蒿7 小时前
Flutter for OpenHarmony: Flutter 三方库 shamsi_date 助力鸿蒙应用精准适配波斯历法(中东出海必备)
android·flutter·ui·华为·自动化·harmonyos
代码飞天8 小时前
wireshark的高级使用
android·java·wireshark
2501_915918419 小时前
苹果App Store上架审核卡住原因分析与解决方案指南
android·ios·小程序·https·uni-app·iphone·webview
skiy9 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
小小小点9 小时前
Android四大常用布局详解与实战
android
MinQ10 小时前
binder和socket区别及原理
android