在 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() {@Overridepublic 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() {@Overridepublic 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 |
注意事项
-
蓝牙权限:Android 12+ 需动态申请
BLUETOOTH_CONNECT
。 -
主线程限制:所有蓝牙操作(如
connect()
)需在子线程执行。 -
设备兼容性:部分旧设备可能不支持 A2DP 或 HFP 的完整功能。