在蓝牙开发中,很多开发者会困惑:"为什么设备能被搜索到?""配对和连接的底层逻辑是什么?""不同设备之间如何实现身份识别?"------这些问题的答案,都藏在GAP(Generic Access Profile,通用访问协议) 中。
GAP是蓝牙协议栈的基础协议之一,也是所有蓝牙设备(经典蓝牙、低功耗蓝牙BLE)必须遵循的"通用规则"。它不负责数据传输本身,却掌管着蓝牙设备的"对外交互":从设备广播、被搜索,到配对认证、连接管理,每一步都离不开GAP的规范。可以说,GAP是蓝牙设备的"社交礼仪",没有它,不同厂商的蓝牙设备就无法互联互通。
本文将从GAP的核心定义、核心功能入手,用通俗的语言拆解其工作原理,再结合iOS(OC)、Flutter、Android(Java)三种主流开发语言的实战代码,帮你快速掌握GAP协议的开发应用,解决蓝牙开发中"设备交互"的核心痛点。
注意:本文聚焦GAP协议的核心实战场景,代码示例均为基础可复用版本,适配经典蓝牙和BLE通用场景,可直接复制到项目中扩展使用。
一、先搞懂:GAP协议到底是什么?
1. 核心定义
GAP通用访问协议,本质是蓝牙设备之间"建立交互"的通用规范,它定义了蓝牙设备的角色、状态、交互流程,以及设备如何对外展示自己、与其他设备建立关联。
简单来说,GAP的作用就是"让两个蓝牙设备认识彼此、建立信任、搭建沟通的基础"。它位于蓝牙协议栈的最上层,直接面向应用层,所有蓝牙设备的"对外操作"(广播、扫描、配对、连接),都需要通过GAP协议来实现。
2. GAP的核心角色(必懂)
GAP定义了两种核心角色,所有蓝牙设备在交互时,必然处于其中一种(可动态切换),这是理解GAP的关键:
- 广播者(Advertiser) :主动发送广播包,对外"自我介绍"的设备(如耳机、智能手表、BLE传感器),核心作用是让其他设备发现自己。对应之前提到的"从设备(Slave)"。
- 扫描者(Scanner) :主动扫描周围的广播包,寻找其他设备的设备(如手机、平板),核心作用是发现广播者,进而发起连接。对应之前提到的"主设备(Master)"。
补充:同一台设备可以同时扮演两种角色(如手机既能扫描耳机,也能开启广播让其他设备发现),角色切换由应用层根据需求控制。
3. GAP的核心功能(开发重点)
GAP的所有功能,都围绕"设备交互"展开,核心可分为4类,也是开发中最常用的场景:
- 广播管理:广播者发送广播包(包含设备名称、MAC地址、服务UUID等信息),控制广播间隔、广播功率;
- 扫描管理:扫描者扫描周围的广播包,过滤目标设备,获取广播者的基础信息;
- 配对管理:实现设备间的身份认证,协商加密密钥,保存配对信息(避免重复配对);
- 连接管理:建立、维持、断开设备间的连接,管理连接状态(如连接成功、连接失败、断开重连)。
这里需要注意:GAP只负责"建立连接",不负责"数据传输";数据传输由后续的GATT协议负责,但GAP是GATT协议的前置基础------没有GAP建立的连接,GATT就无法传输数据。
二、GAP核心功能实战:多平台代码示例
下面针对GAP的4个核心功能,分别提供iOS(OC)、Flutter、Android(Java)的实战代码,覆盖"广播、扫描、配对、连接"全场景,代码可直接复用,重点标注GAP相关的核心API。
1. 功能1:广播管理(GAP广播者角色)
场景:让设备开启广播,对外发送"自我介绍",供其他设备扫描发现(如BLE传感器主动广播自己的存在)。
(1)iOS(OC)------ BLE广播开启(GAP广播者)
objectivec
// 导入GAP相关头文件(CoreBluetooth已封装GAP协议)
#import <CoreBluetooth/CoreBluetooth.h>
@interface GAPAdvertiserManager () <CBPeripheralManagerDelegate>
@property (nonatomic, strong) CBPeripheralManager *peripheralManager; // GAP广播核心管理器
@end
@implementation GAPAdvertiserManager
- (instancetype)init {
self = [super init];
if (self) {
// 初始化GAP广播管理器(底层已实现GAP协议)
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
}
return self;
}
// 监听广播管理器状态,状态就绪后开启广播(GAP核心操作)
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
if (peripheral.state == CBManagerStatePoweredOn) {
NSLog(@"GAP广播者就绪,开始发送广播(GAP协议)");
// 配置GAP广播包信息(符合GAP规范,包含设备名称、服务UUID)
NSDictionary *advertisementData = @{
// 设备名称(GAP广播包必填字段,供扫描者识别)
CBAdvertisementDataLocalNameKey: @"GAP-Device",
// 服务UUID(GAP广播包可选,用于过滤目标设备)
CBAdvertisementDataServiceUUIDsKey: @[[CBUUID UUIDWithString:@"0000FFE0-0000-1000-8000-00805F9B34FB"]]
};
// 开启GAP广播(底层GAP协议自动处理广播信道、广播间隔)
// 广播间隔默认由系统控制,可通过options参数自定义(如缩短间隔提升被发现速度)
[self.peripheralManager startAdvertising:advertisementData];
}
}
// 监听GAP广播开启结果
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {
if (error) {
NSLog(@"GAP广播开启失败:%@", error.localizedDescription);
} else {
NSLog(@"GAP广播开启成功,在3个广播信道(37、38、39)发送广播(GAP规范)");
}
}
// 停止GAP广播(GAP协议操作)
- (void)stopGAPAdvertising {
if (self.peripheralManager.isAdvertising) {
[self.peripheralManager stopAdvertising];
NSLog(@"GAP广播已停止");
}
}
@end
(2)Flutter------ BLE广播开启(GAP广播者,依赖flutter_blue_plus)
dart
// 导入依赖(pubspec.yaml中添加:flutter_blue_plus: ^1.13.3)
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// 开启GAP广播(GAP广播者角色)
Future<void> startGAPAdvertising() async {
// 检查蓝牙状态,开启蓝牙(GAP广播前提)
if (await FlutterBluePlus.isOn == false) {
await FlutterBluePlus.turnOn();
}
// 配置GAP广播包信息(符合GAP协议规范)
Map<String, dynamic> gapAdvertisementData = {
'localName': 'GAP-Device', // 设备名称(GAP必填)
'serviceUuids': ['0000FFE0-0000-1000-8000-00805F9B34FB'], // 服务UUID(GAP可选)
'manufacturerData': [0x00, 0x01] // 厂商数据(GAP扩展字段)
};
try {
// 开启GAP广播(插件底层已封装GAP协议,自动处理广播逻辑)
await FlutterBluePlus.startAdvertising(gapAdvertisementData);
print("GAP广播开启成功,遵循GAP协议发送广播");
} catch (e) {
print("GAP广播开启失败:$e");
}
}
// 停止GAP广播
Future<void> stopGAPAdvertising() async {
if (await FlutterBluePlus.isAdvertising) {
await FlutterBluePlus.stopAdvertising();
print("GAP广播已停止");
}
}
(3)Android(Java)------ BLE广播开启(GAP广播者)
java
// 导入GAP相关包(Android蓝牙API已封装GAP协议)
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.os.ParcelUuid;
import java.util.UUID;
// GAP广播者实现类
public class GAPAdvertiser {
private BluetoothLeAdvertiser advertiser; // GAP广播核心对象
// 开启GAP广播
public void startGAPAdvertising() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
System.out.println("蓝牙未开启,无法启动GAP广播");
return;
}
// 获取GAP广播对象(仅BLE设备支持,经典蓝牙广播逻辑略有不同)
advertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
if (advertiser == null) {
System.out.println("设备不支持GAP广播");
return;
}
// 配置GAP广播设置(符合GAP协议,控制广播功率、间隔)
AdvertiseSettings gapAdvertiseSettings = new AdvertiseSettings.Builder()
.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) // 低延迟(优先被发现)
.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) // 高功率广播
.setConnectable(true) // 可连接(GAP广播核心标识,说明设备可被连接)
.build();
// 配置GAP广播包数据(符合GAP规范)
AdvertiseData gapAdvertiseData = new AdvertiseData.Builder()
.setIncludeDeviceName(true) // 包含设备名称(GAP必填)
.addServiceUuid(new ParcelUuid(UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB"))) // 服务UUID
.build();
// 开启GAP广播(底层GAP协议自动处理广播信道、广播逻辑)
advertiser.startAdvertising(gapAdvertiseSettings, gapAdvertiseData, new AdvertiseCallback() {
@Override
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
super.onStartSuccess(settingsInEffect);
System.out.println("GAP广播开启成功,遵循GAP协议发送广播");
}
@Override
public void onStartFailure(int errorCode) {
super.onStartFailure(errorCode);
System.out.println("GAP广播开启失败,错误码:" + errorCode);
}
});
}
// 停止GAP广播
public void stopGAPAdvertising() {
if (advertiser != null) {
advertiser.stopAdvertising(new AdvertiseCallback() {});
System.out.println("GAP广播已停止");
}
}
}
2. 功能2:扫描管理(GAP扫描者角色)
场景:设备主动扫描周围的GAP广播,发现目标设备,获取广播包中的设备信息(如设备名称、MAC地址),为后续配对、连接做准备(如手机扫描耳机)。
(1)iOS(OC)------ BLE扫描(GAP扫描者)
objectivec
// 导入GAP相关头文件
#import <CoreBluetooth/CoreBluetooth.h>
@interface GAPScannerManager () <CBCentralManagerDelegate>
@property (nonatomic, strong) CBCentralManager *centralManager; // GAP扫描核心管理器
@end
@implementation GAPScannerManager
- (instancetype)init {
self = [super init];
if (self) {
// 初始化GAP扫描管理器(底层已实现GAP扫描协议)
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:@{CBCentralManagerOptionShowPowerAlertKey: @YES}];
}
return self;
}
// 监听扫描管理器状态,就绪后开始扫描(GAP核心操作)
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
if (central.state == CBManagerStatePoweredOn) {
NSLog(@"GAP扫描者就绪,开始扫描周围GAP广播(GAP协议)");
// 开始GAP扫描(底层自动扫描3个广播信道,符合GAP规范)
// options参数:设置是否允许重复扫描(NO表示只扫描一次,提升效率)
[central scanForPeripheralsWithServices:nil options:@{CBCentralManagerScanOptionAllowDuplicatesKey: @NO}];
}
}
// 发现GAP广播设备(GAP扫描核心回调,获取广播包信息)
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
// 从GAP广播包中获取设备信息(符合GAP协议规范的字段)
NSString *deviceName = advertisementData[CBAdvertisementDataLocalNameKey] ?: @"未知设备";
NSString *deviceUUID = peripheral.identifier.UUIDString; // 设备唯一标识(GAP协议定义)
NSNumber *signalStrength = RSSI; // 信号强度(GAP广播包扩展字段)
NSLog(@"发现GAP广播设备:名称=%@,UUID=%@,信号强度=%@ dBm", deviceName, deviceUUID, signalStrength);
// 过滤目标设备(根据设备名称,符合GAP扫描逻辑)
if ([deviceName isEqualToString:@"GAP-Device"]) {
NSLog(@"发现目标GAP设备,停止扫描");
[central stopScan]; // 停止扫描,准备发起连接
// 后续可调用GAP连接、配对逻辑
}
}
// 停止GAP扫描
- (void)stopGAPScanning {
if (self.centralManager.isScanning) {
[self.centralManager stopScan];
NSLog(@"GAP扫描已停止");
}
}
@end
(2)Flutter------ BLE扫描(GAP扫描者,依赖flutter_blue_plus)
dart
// 导入依赖
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// 开始GAP扫描(扫描周围的GAP广播设备)
Future<void> startGAPScanning() async {
// 检查蓝牙状态,开启蓝牙(GAP扫描前提)
if (await FlutterBluePlus.isOn == false) {
await FlutterBluePlus.turnOn();
}
// 开始GAP扫描(插件底层封装GAP协议,自动扫描3个广播信道)
// timeout:扫描超时时间(10秒),符合GAP扫描效率规范
FlutterBluePlus.startScan(timeout: const Duration(seconds: 10));
print("GAP扫描已开始,正在扫描周围GAP广播设备");
// 监听GAP扫描结果(获取广播包信息,符合GAP协议)
FlutterBluePlus.scanResults.listen((List<ScanResult> results) {
for (ScanResult result in results) {
// 从GAP广播包中提取设备信息
String deviceName = result.device.name ?? "未知设备";
String deviceAddress = result.device.address; // 设备MAC地址(GAP协议定义)
int signalStrength = result.rssi; // 信号强度
print("发现GAP设备:名称=$deviceName,地址=$deviceAddress,信号强度=$signalStrength dBm");
// 过滤目标GAP设备
if (deviceName == "GAP-Device") {
print("发现目标GAP设备,停止扫描");
FlutterBluePlus.stopScan();
// 后续可发起GAP连接、配对
}
}
});
}
// 停止GAP扫描
Future<void> stopGAPScanning() async {
if (FlutterBluePlus.isScanningNow) {
FlutterBluePlus.stopScan();
print("GAP扫描已停止");
}
}
(3)Android(Java)------ BLE扫描(GAP扫描者)
csharp
// 导入GAP相关包
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
// GAP扫描者实现类
public class GAPScanner {
private BluetoothLeScanner scanner; // GAP扫描核心对象
// 开始GAP扫描
public void startGAPScanning() {
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
System.out.println("蓝牙未开启,无法启动GAP扫描");
return;
}
// 获取GAP扫描对象(底层已实现GAP扫描协议)
scanner = bluetoothAdapter.getBluetoothLeScanner();
if (scanner == null) {
System.out.println("设备不支持GAP扫描");
return;
}
// 开始GAP扫描(符合GAP规范,自动扫描3个广播信道)
scanner.startScan(new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
// 从GAP广播包中提取设备信息(符合GAP协议)
String deviceName = result.getDevice().getName() == null ? "未知设备" : result.getDevice().getName();
String deviceAddress = result.getDevice().getAddress(); // 设备MAC地址(GAP定义)
int signalStrength = result.getRssi(); // 信号强度
System.out.println("发现GAP设备:名称=" + deviceName + ",地址=" + deviceAddress + ",信号强度=" + signalStrength + " dBm");
// 过滤目标GAP设备
if ("GAP-Device".equals(deviceName)) {
System.out.println("发现目标GAP设备,停止扫描");
stopGAPScanning();
// 后续可发起GAP连接、配对
}
}
});
System.out.println("GAP扫描已开始,遵循GAP协议扫描广播设备");
}
// 停止GAP扫描
public void stopGAPScanning() {
if (scanner != null) {
scanner.stopScan(new ScanCallback() {});
System.out.println("GAP扫描已停止");
}
}
}
3. 功能3:配对管理(GAP核心交互)
场景:扫描到目标设备后,通过GAP协议完成身份认证(配对),协商加密密钥,确保设备间的通信安全,这是GAP协议的核心安全功能。
(1)iOS(OC)------ GAP配对监听(系统自动处理配对流程)
objectivec
// 继续使用上面的GAP扫描者管理器,连接后监听GAP配对状态
#import <CoreBluetooth/CoreBluetooth.h>
@interface GAPPairManager () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheral *targetPeripheral; // 目标GAP设备
@end
@implementation GAPPairManager
// 连接目标GAP设备,触发GAP配对
- (void)connectToGAPDevice:(CBPeripheral *)peripheral {
self.targetPeripheral = peripheral;
self.targetPeripheral.delegate = self;
// 发起GAP连接(连接成功后,系统自动触发GAP配对流程,符合GAP协议)
[self.centralManager connectPeripheral:peripheral options:nil];
}
// GAP连接成功,开始监听配对状态(GAP配对核心回调)
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"GAP设备连接成功,触发GAP配对流程");
// 发现设备服务(间接判断配对状态,符合GAP协议逻辑)
[peripheral discoverServices:nil];
}
// 监听GAP配对状态(通过服务发现结果判断配对是否成功)
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
if (error) {
NSLog(@"GAP配对失败:%@(可能未完成身份认证)", error.localizedDescription);
return;
}
// 服务发现成功,说明GAP配对已完成(iOS系统自动处理配对弹窗,无需手动干预)
NSLog(@"GAP配对成功,已完成身份认证,可进行后续数据传输");
}
// 辅助方法:判断设备是否已完成GAP配对
- (BOOL)isGAPPaired:(CBPeripheral *)peripheral {
// GAP配对信息由系统保存,通过获取已连接设备列表判断
NSArray *pairedPeripherals = [self.centralManager retrieveConnectedPeripheralsWithServices:nil];
for (CBPeripheral *p in pairedPeripherals) {
if ([p.identifier isEqualToString:peripheral.identifier]) {
return YES;
}
}
return NO;
}
@end
(2)Flutter------ GAP配对监听(依赖flutter_blue_plus)
dart
// 导入依赖
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// 连接GAP设备并监听配对状态(GAP配对流程)
Future<void> connectAndMonitorGAPPairing(BluetoothDevice device) async {
try {
// 发起GAP连接(连接成功后,触发GAP配对流程)
await device.connect();
print("GAP设备连接成功,开始GAP配对");
// 监听GAP配对状态(通过服务发现结果判断,符合GAP协议)
device.discoverServices().then((List<BluetoothService> services) {
if (services.isNotEmpty) {
print("GAP配对成功,已完成身份认证,获取到设备服务");
}
}).catchError((error) {
print("GAP配对失败:$error(可能未完成身份认证)");
});
// 监听GAP配对后的连接状态
device.connectionState.listen((BluetoothConnectionState state) {
if (state == BluetoothConnectionState.connected) {
print("GAP配对后,设备保持连接状态");
} else if (state == BluetoothConnectionState.disconnected) {
print("GAP配对后连接断开,可尝试重新配对连接");
}
});
} catch (e) {
print("GAP设备连接失败,无法触发配对:$e");
}
}
// 断开GAP配对连接
Future<void> disconnectGAPPairedDevice(BluetoothDevice device) async {
if (device.connectionState == BluetoothConnectionState.connected) {
await device.disconnect();
print("GAP配对连接已断开");
}
}
(3)Android(Java)------ GAP配对发起与监听
java
// 导入GAP配对相关包
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.IntentFilter;
import android.content.BroadcastReceiver;
import android.content.Intent;
// GAP配对管理器(发起配对、监听配对状态)
public class GAPPairManager {
private Context context;
public GAPPairManager(Context context) {
this.context = context;
}
// 发起GAP配对(经典蓝牙,符合GAP协议规范)
public void startGAPPairing(BluetoothDevice device) {
// 注册广播接收器,监听GAP配对状态(Android系统GAP配对回调)
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
context.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
// 取消系统默认配对弹窗,手动处理GAP配对(可选)
abortBroadcast();
BluetoothDevice pairedDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// 发起GAP配对(经典蓝牙需输入PIN码,符合GAP协议,此处以0000为例)
pairedDevice.setPin(new byte[]{0x30, 0x30, 0x30, 0x30});
pairedDevice.setPairingConfirmation(true);
System.out.println("GAP配对成功:" + pairedDevice.getName());
}
}
}, filter);
// 发起GAP配对请求(通过反射调用,符合GAP协议)
try {
java.lang.reflect.Method method = BluetoothDevice.class.getMethod("createBond");
method.invoke(device);
System.out.println("发起GAP配对请求:" + device.getName());
} catch (Exception e) {
e.printStackTrace();
System.out.println("GAP配对请求失败:" + e.getMessage());
}
}
// BLE设备GAP配对(连接后自动配对,符合GAP协议)
public void connectAndPairGAPBLEDevice(BluetoothDevice device) {
// 发起GAP连接,连接成功后自动触发配对
device.connectGatt(context, false, new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
System.out.println("GAP BLE设备连接成功,自动触发GAP配对");
gatt.discoverServices(); // 发现服务,确认配对成功
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
System.out.println("GAP配对连接断开");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
System.out.println("GAP BLE配对成功,已完成身份认证");
} else {
System.out.println("GAP BLE配对失败,服务发现失败");
}
}
});
}
}
4. 功能4:连接管理(GAP协议收尾)
场景:GAP配对成功后,建立稳定的连接链路,管理连接状态(连接成功、断开、重连),为后续GATT数据传输提供基础。
(1)iOS(OC)------ GAP连接管理
objectivec
// 继续使用GAPPairManager,完善GAP连接管理逻辑
#import <CoreBluetooth/CoreBluetooth.h>
@interface GAPConnectionManager () <CBCentralManagerDelegate, CBPeripheralDelegate>
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic, strong) CBPeripheral *connectedPeripheral; // 已连接的GAP设备
@end
@implementation GAPConnectionManager
// 发起GAP连接(配对后建立连接,符合GAP协议)
- (void)connectGAPDevice:(CBPeripheral *)peripheral {
self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil options:nil];
if (self.centralManager.state == CBManagerStatePoweredOn) {
NSLog(@"发起GAP连接:%@", peripheral.name);
[self.centralManager connectPeripheral:peripheral options:nil];
}
}
// GAP连接成功(GAP协议核心回调)
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
self.connectedPeripheral = peripheral;
peripheral.delegate = self;
NSLog(@"GAP连接成功:%@,已建立稳定链路(GAP协议)", peripheral.name);
// 发现设备服务,准备后续数据传输
[peripheral discoverServices:nil];
}
// GAP连接失败(GAP协议异常处理)
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"GAP连接失败:%@,错误信息:%@", peripheral.name, error.localizedDescription);
// 重试连接(符合GAP连接重试规范)
[central connectPeripheral:peripheral options:nil];
}
// GAP连接断开(GAP协议异常处理)
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"GAP连接断开:%@,错误信息:%@", peripheral.name, error.localizedDescription);
self.connectedPeripheral = nil;
// 重新扫描并连接(符合GAP连接管理逻辑)
[central scanForPeripheralsWithServices:nil options:nil];
}
// 断开GAP连接
- (void)disconnectGAPDevice {
if (self.connectedPeripheral && self.centralManager.isConnected(self.connectedPeripheral)) {
[self.centralManager cancelPeripheralConnection:self.connectedPeripheral];
NSLog(@"GAP连接已主动断开");
}
}
@end
(2)Flutter------ GAP连接管理(依赖flutter_blue_plus)
dart
// 导入依赖
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
// GAP连接管理类
class GAPConnectionManager {
BluetoothDevice? _connectedDevice; // 已连接的GAP设备
// 发起GAP连接
Future<void> connectGAPDevice(BluetoothDevice device) async {
try {
if (await FlutterBluePlus.isOn == false) {
await FlutterBluePlus.turnOn();
}
// 发起GAP连接(符合GAP协议,配对后建立连接)
await device.connect(autoConnect: false);
_connectedDevice = device;
print("GAP连接成功:${device.name},建立稳定链路");
// 监听GAP连接状态变化
device.connectionState.listen((BluetoothConnectionState state) {
switch (state) {
case BluetoothConnectionState.connected:
print("GAP连接保持稳定");
break;
case BluetoothConnectionState.disconnected:
print("GAP连接断开,尝试重连");
reconnectGAPDevice(device); // 自动重连
break;
default:
break;
}
});
} catch (e) {
print("GAP连接失败:$e");
}
}
// GAP连接重连(符合GAP协议异常处理)
Future<void> reconnectGAPDevice(BluetoothDevice device) async {
try {
await device.connect(autoConnect: true);
_connectedDevice = device;
print("GAP设备重连成功:${device.name}");
} catch (e) {
print("GAP设备重连失败:$e");
}
}
// 断开GAP连接
Future<void> disconnectGAPDevice() async {
if (_connectedDevice != null &&
_connectedDevice!.connectionState == BluetoothConnectionState.connected) {
await _connectedDevice!.disconnect();
_connectedDevice = null;
print("GAP连接已主动断开");
}
}
}
(3)Android(Java)------ GAP连接管理
typescript
// 导入GAP连接相关包
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
// GAP连接管理器
public class GAPConnectionManager {
private Context context;
private BluetoothGatt gatt; // GAP连接核心对象
public GAPConnectionManager(Context context) {
this.context = context;
}
// 发起GAP连接(BLE设备,符合GAP协议)
public void connectGAPDevice(BluetoothDevice device) {
// 发起GAP连接,获取GATT对象(GAP连接的核心载体)
gatt = device.connectGatt(context, false, new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
System.out.println("GAP连接成功:" + gatt.getDevice().getName());
// 发现服务,准备数据传输
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
System.out.println("GAP连接断开,尝试重连");
reconnectGAPDevice(device); // 自动重连
}
}
});
}
// GAP连接重连(符合GAP协议异常处理)
public void reconnectGAPDevice(BluetoothDevice device) {
if (gatt != null) {
gatt.connect();
System.out.println("GAP设备重连中:" + device.getName());
} else {
connectGAPDevice(device);
}
}
// 断开GAP连接
public void disconnectGAPDevice() {
if (gatt != null) {
gatt.disconnect();
gatt.close();
gatt = null;
System.out.println("GAP连接已主动断开");
}
}
}
三、GAP开发注意事项(避坑重点)
- GAP协议是"通用规范",无论经典蓝牙还是BLE,都必须遵循,开发时无需区分,重点关注角色(广播者/扫描者)即可;
- 广播包大小限制:GAP广播包最大31字节(BLE),经典蓝牙略大,开发时避免在广播包中携带过多数据,仅传递设备基础信息;
- 配对流程:iOS/Flutter的GAP配对由系统自动处理,开发者仅能监听状态;Android可手动处理配对(如自定义PIN码),但需遵循GAP协议规范;
- 连接稳定性:GAP连接后,需监听连接状态,实现重连逻辑,避免因设备远离、信号干扰导致连接断开;
- 权限问题:多平台开发时,需申请蓝牙权限(如iOS的NSBluetoothAlwaysUsageDescription,Android的BLUETOOTH、BLUETOOTH_ADMIN等),否则无法正常使用GAP功能。
四、总结:GAP协议的核心价值
GAP通用访问协议,是蓝牙设备"互联互通"的基础------它定义了设备如何"自我介绍"(广播)、如何"寻找朋友"(扫描)、如何"建立信任"(配对)、如何"保持联系"(连接)。没有GAP,不同厂商、不同类型的蓝牙设备就无法相互识别、建立连接。
对于开发者而言,掌握GAP协议,就是掌握了蓝牙开发的"入门钥匙":无论是智能硬件、物联网设备,还是手机端蓝牙应用,所有涉及"设备交互"的场景,都离不开GAP的核心操作。