蓝牙GAP通用访问协议详解:从原理到多平台实战代码

在蓝牙开发中,很多开发者会困惑:"为什么设备能被搜索到?""配对和连接的底层逻辑是什么?""不同设备之间如何实现身份识别?"------这些问题的答案,都藏在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类,也是开发中最常用的场景:

  1. 广播管理:广播者发送广播包(包含设备名称、MAC地址、服务UUID等信息),控制广播间隔、广播功率;
  2. 扫描管理:扫描者扫描周围的广播包,过滤目标设备,获取广播者的基础信息;
  3. 配对管理:实现设备间的身份认证,协商加密密钥,保存配对信息(避免重复配对);
  4. 连接管理:建立、维持、断开设备间的连接,管理连接状态(如连接成功、连接失败、断开重连)。

这里需要注意: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的核心操作。

相关推荐
maaath2 小时前
【maaath】Flutter for OpenHarmony 集成应用更新能力
flutter·华为·harmonyos
maaath2 小时前
【maaath】 OpenHarmony 设备信息获取能力集成指南
flutter·华为·harmonyos
byte轻骑兵2 小时前
【HID】规范精讲[6]: 蓝牙HID系统设计指南——从合规到体验的全维度要求
人机交互·蓝牙·键盘·鼠标·遥控·hid
Hello__77772 小时前
开源鸿蒙 Flutter 实战|帮助中心功能全流程实现
flutter·开源·harmonyos
Hello__77772 小时前
开源鸿蒙 Flutter 实战|用户认证标识功能全流程实现
flutter·开源·harmonyos
Hello__77773 小时前
开源鸿蒙 Flutter 实战|用户详情页按钮布局溢出全流程修复与最佳实践
flutter·开源·harmonyos
yanlaifan3 小时前
经典蓝牙中信道和链路的关系
蓝牙
恋猫de小郭3 小时前
Flutter 3.41.8 又双叒修复调试问题,草台班子日常 hotfix
android·前端·flutter
liulian09163 小时前
【Flutter for OpenHarmony第三方库】Flutter for OpenHarmony 离线模式实现:让你的应用无网也能萌萌哒~
开发语言·flutter·华为·php·学习方法·harmonyos