You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-native-ble-manager配置失效:iOS真机无法扫描BLE设备

iOS真机测试React Native BLE扫描无响应,扫描结束事件未触发

尝试在App.tsx中配置发现附近BLE设备,已遵循各类教程操作,但iOS真机测试时无法正常运行。权限已配置正确,推测监听功能异常——10秒扫描计时器到期后未输出预期的“Scan stopped”日志,也看不到外设发现的日志。后续计划用Map渲染设备列表,当前代码如下:

import "./i18n";
import BeaconButton from "@components/UI/BeaconButton";
import { handleAndroidPermissions } from "@utils/androidPermissions";
import { checkLocationPermissions } from "@utils/location";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import {
  SafeAreaView,
  ScrollView,
  Text,
  View,
  Platform,
  Alert,
  NativeModules,
  NativeEventEmitter,
  DeviceEventEmitter,
  FlatList,
  EmitterSubscription,
} from "react-native";
import BleManager, {
  Peripheral as BlePeripheral,
} from "react-native-ble-manager";

interface Peripheral extends BlePeripheral {
  connected?: boolean;
}

export default function App() {
  const BleManagerModule = NativeModules.BleManager;
  const BleManagerEmitter = new NativeEventEmitter(BleManagerModule);

  const [isScanning, setIsScanning] = useState<boolean>(false);

  const { t } = useTranslation("location");


  const startScan = async () => {
    if (!isScanning) {
      try {
        console.log("Starting scan...");
        await BleManager.scan([], 10, false); 
        setIsScanning(true);
        console.log("Scan started");
      } catch (error) {
        console.error("Scan error:", error);
      }
    }
  };

  useEffect(() => {
    const initBle = async () => {
      try {
        // 1. Ask to enable Bluetooth
        if (Platform.OS === "android") {
          try {
            await BleManager.enableBluetooth();
            console.log("Bluetooth is turned on!");
          } catch {
            Alert.alert(
              "Bluetooth Required",
              "Please enable Bluetooth to continue."
            );
            throw new Error("Bluetooth not enabled");
          }
        }

        // 2. Request permissions
        await handleAndroidPermissions();
        await checkLocationPermissions(t);

        // 3. Start BLE manager
        await BleManager.start({ showAlert: false });
        console.log("BleManager started and ready.");
      } catch (err) {
        console.error("Error initializing BLE:", err);
      }
    };

    initBle();
  }, []);

 useEffect(() => {
    const discoverListener = BleManagerEmitter.addListener(
      "BleManagerDiscoverPeripheral",
      (peripheral) => {
        console.log("Discovered:", peripheral);
      }
    );

    return () => discoverListener.remove();
  }, []);

  useEffect(() => {
    let stopListener = BleManagerEmitter.addListener(
      "BleManagerStopScan",
      () => {
        setIsScanning(false);
        console.log("Scan stopped");
      }
    );

    return () => stopListener.remove();
  }, []);

  return (
    <SafeAreaView className="flex-1 bg-&quot;">
      <View className="flex-1 items-center px-5 pt-4">
        <ScrollView className="w-full p-5 mt-32 bg-red-100">
          {/* render devices here */}
        </ScrollView>
        <BeaconButton
          className="bg-blue-500 rounded-lg mt-8"
          textClassName="text-white"
          onPress={startScan}
        >
          {isScanning ? "Scanning..." : "Scan Bluetooth Devices"}
        </BeaconButton>
      </View>
    </SafeAreaView>
  );
}

排查与修复步骤

1. 补全iOS蓝牙状态检查

代码仅处理了Android的蓝牙开启请求,iOS端未校验蓝牙状态,导致扫描静默失败。添加iOS蓝牙检查逻辑:

// 在initBle函数的蓝牙检查部分补充
if (Platform.OS === "ios") {
  const isEnabled = await BleManager.isBluetoothEnabled();
  if (!isEnabled) {
    Alert.alert(
      "蓝牙需要开启",
      "请前往设置开启蓝牙以继续"
    );
    throw new Error("蓝牙未开启");
  }
}

2. 修正iOS扫描参数

BleManager.scan的第三个参数allowDuplicates在iOS上默认行为限制较多,设为true可确保扫描事件正常触发,避免提前终止:

// 修改startScan中的扫描调用
await BleManager.scan([], 10, true);

3. 确认权限配置完整性

确保Info.plist中已添加iOS 13+所需的蓝牙与位置权限:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>需要蓝牙权限以发现附近的BLE设备</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>需要蓝牙权限以连接BLE设备</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要位置权限以扫描BLE设备</string>

4. 修复代码语法错误

SafeAreaView的className存在语法错误,修正为合法样式值:

<SafeAreaView className="flex-1 bg-white">

5. 验证监听注册时机

确保事件监听在BleManager.start完成后注册,若仍有问题,可将监听逻辑移至initBle的成功回调中:

// 在initBle的try块末尾添加监听注册
const setupListeners = () => {
  const discoverListener = BleManagerEmitter.addListener(
    "BleManagerDiscoverPeripheral",
    (peripheral) => {
      console.log("Discovered:", peripheral);
    }
  );

  const stopListener = BleManagerEmitter.addListener(
    "BleManagerStopScan",
    () => {
      setIsScanning(false);
      console.log("Scan stopped");
    }
  );

  return () => {
    discoverListener.remove();
    stopListener.remove();
  };
};

const cleanup = setupListeners();
// 在useEffect的返回中调用cleanup

验证流程

  1. 重启iOS真机蓝牙,重新运行App
  2. 点击扫描按钮,确认控制台输出“Scan started”
  3. 等待10秒,检查“Scan stopped”日志是否出现
  4. 附近放置BLE设备,查看是否输出“Discovered”日志

内容的提问来源于stack exchange,提问作者Roberto Quadraccia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:06:05