Android 蓝牙/Wi-Fi通信协议之:经典蓝牙(BT 2.1/3.0+)介绍

发布于:2025-03-29 ⋅ 阅读:(28) ⋅ 点赞:(0)

在 Android 开发中,经典蓝牙(BT 2.1/3.0+)支持多种协议,其中 RFCOMM/SPP(串口通信)、A2DP(音频流传输)和 HFP(免提通话)是最常用的。以下是它们在 Android 中的实现详解:

  • 经典蓝牙(BT 2.1/3.0+)

    • 协议栈:RFCOMM(串口模拟)、SPP(串行端口协议)、A2DP(音频传输)、HFP(免提协议)。

    • 用途:大文件传输、音频设备(耳机/音箱)。

    • 带宽:1-3 Mbps,功耗较高。


1. RFCOMM & SPP(串口通信)

协议作用

  • RFCOMM(Serial Port Emulation):模拟串口通信,提供可靠的串行数据传输(类似 UART)。

  • SPP(Serial Port Profile):基于 RFCOMM,定义蓝牙设备间的虚拟串口通信标准。

Android 实现

1.1 权限申请
<uses-permission android:name="android.permission.BLUETOOTH" /> 
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <!-- Android 12+ 需要额外权限 --> 
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
1.2 设备配对与连接
// 获取 BluetoothAdapter
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// 发现设备(需先启用蓝牙)
bluetoothAdapter.startDiscovery();

// 绑定到已配对设备
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
BluetoothDevice targetDevice = pairedDevices.iterator().next(); // 示例:选择第一个设备

// 通过 UUID 建立 RFCOMM 连接(SPP 标准 UUID:00001101-0000-1000-8000-00805F9B34FB)
UUID sppUuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothSocket socket = targetDevice.createRfcommSocketToServiceRecord(sppUuid);
socket.connect(); // 阻塞式连接,需在子线程执行
1.3 数据传输

// 获取输入输出流
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();

// 发送数据
outputStream.write("Hello Bluetooth".getBytes());

// 接收数据(需循环读取)
byte[] buffer = new byte[1024];
int bytes = inputStream.read(buffer);
String receivedData = new String(buffer, 0, bytes);

2. A2DP(高级音频分发协议)

协议作用

  • 用于蓝牙立体声音频传输(如音乐播放),单向传输(手机→音箱)。

  • 不支持麦克风(录音需结合 HFP 或 SCO)。

Android 实现

2.1 权限
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
2.2 连接 A2DP 设备
// 获取 A2DP 代理
BluetoothA2dp bluetoothA2dp = BluetoothAdapter.getDefaultAdapter().getProfileProxy(
    context, 
    new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.A2DP) {
                bluetoothA2dp = (BluetoothA2dp) proxy;
            }
        }
    }, 
    BluetoothProfile.A2DP
);

// 连接设备(需已配对)
List<BluetoothDevice> connectedDevices = bluetoothA2dp.getConnectedDevices();
if (!connectedDevices.isEmpty()) {
    BluetoothDevice audioDevice = connectedDevices.get(0);
}
2.3 音频路由控制

Android 实现

  • 音频默认通过 A2DP 设备播放(系统自动处理)。

  • 可通过 AudioManager 强制切换:

    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    audioManager.setBluetoothA2dpOn(true); // 启用 A2DP 输出

    3. HFP(免提协议)

    协议作用

  • 支持蓝牙通话功能(双向音频):麦克风输入 + 听筒输出。

  • 常用于车载免提、耳机通话场景。

3.1 权限
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
3.2 连接 HFP 设备
// 获取 HFP 代理
BluetoothHeadset bluetoothHeadset = BluetoothAdapter.getDefaultAdapter().getProfileProxy(
    context, 
    new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            if (profile == BluetoothProfile.HEADSET) {
                bluetoothHeadset = (BluetoothHeadset) proxy;
            }
        }
    }, 
    BluetoothProfile.HEADSET
);

// 检查设备连接状态
List<BluetoothDevice> connectedDevices = bluetoothHeadset.getConnectedDevices();
boolean isConnected = (connectedDevices.size() > 0);
3.3 通话控制

  • 接听/挂断电话(需系统级权限,普通应用无法直接调用):

    // 通过 Intent 间接控制(部分设备支持)
    Intent answerIntent = new Intent(Intent.ACTION_HEADSET_PLUG);
    answerIntent.putExtra("state", 1); // 1 接听,0 挂断
    context.sendBroadcast(answerIntent);

  • 音频路由切换

    
    AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
    audioManager.setBluetoothScoOn(true);  // 启用 SCO 通道(通话音频)
    audioManager.startBluetoothSco();      // 启动 SCO 连接

关键区别总结

协议 方向 用途 音频类型 Android API 类
RFCOMM 双向 串口数据通信 BluetoothSocket
A2DP 单向(输出) 音乐播放 立体声(16-bit) BluetoothA2dp
HFP 双向 通话(麦克风+听筒) 单声道(8kHz) BluetoothHeadset

注意事项

  1. 蓝牙权限:Android 12+ 需动态申请 BLUETOOTH_CONNECT

  2. 主线程限制:所有蓝牙操作(如 connect())需在子线程执行。

  3. 设备兼容性:部分旧设备可能不支持 A2DP 或 HFP 的完整功能。