Skip to content
RN蓝牙扫描设备连接问题
js
import React, { useRef, useEffect } from 'react';
import { View, Text, StyleSheet, Animated, PermissionsAndroid, Platform } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { BleManager } from 'react-native-ble-plx';
const manager = new BleManager();
export const test = () => {
  const scanXinHao =async () => {
    let permissions;
    // 安卓要获取权限,ios会自动弹出
    if(Platform.OS === 'android'){
        if (Platform.Version >= 31) { // Android 12 及以上
        permissions = [
          'android.permission.BLUETOOTH_SCAN',
          'android.permission.BLUETOOTH_CONNECT',
          'android.permission.BLUETOOTH_ADVERTISE'
        ];
      } else { // Android 12 以下
        permissions = ['android.permission.ACCESS_FINE_LOCATION'];
      }
    }
    // 获取权限
    for (const permission of permissions) {
      const check = await PermissionsAndroid.check(permission);
      console.log(`permission ${permission} check ${check}`);
      if (!check) {
        await PermissionsAndroid.request(permission);
      }
    }
    // 开始扫描
    manager.startDeviceScan(null, null, async (error, device) => {
      if (error) {
        // 扫描出错,一般是权限问题
        console.error(error);
        // 停止扫描
        manager.stopDeviceScan()
        console.log('蓝牙扫描出错了~');
        return;
      }
      // 扫描到设备
      console.log(device)
      let a = JSON.stringify(device)
      console.log(a) // 扫描到的设备
      if (device.name === 'Take-73576717') {
        console.log('找到设备了,停止扫描,开始连接')
        manager.stopDeviceScan()
        // 连接设备,并获取是否连接成功,拿到连接成功后返回的信息
        manager.connectToDevice(device.id).then((device) => {
          console.log('连接成功返回的信息', JSON.stringify(device))
        })
      }
    });
  }

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={scanXinHao}>
        <Text>扫描信号</Text>
      </TouchableOpacity>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  }
});

简易的蓝牙扫描连接和断开连接三个逻辑

js
import React, { useEffect, useRef, useState } from 'react';
import { View, SafeAreaView, StyleSheet, Text, PermissionsAndroid, Platform, TouchableOpacity } from 'react-native';
import { BleManager } from 'react-native-ble-plx';

const manager = new BleManager();

export const SyncData = () => {
    const [scanStatus, setScanStatus] = useState('未开始扫描');
    const [connectionStatus, setConnectionStatus] = useState('未连接');
    const [device, setDevice] = useState(null);

    useEffect(() => {
        // 初始化蓝牙管理器
        const subscription = manager.onStateChange((state) => {
            if (state === 'PoweredOn') {
                setScanStatus('蓝牙已开启,可以扫描');
            } else {
                setScanStatus('蓝牙未开启');
            }
        }, true);

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

    // 请求权限
    const requestPermissions = async () => {
        if (Platform.OS === 'android') {
            const permissions = Platform.Version >= 31
                ? ['android.permission.BLUETOOTH_SCAN', 'android.permission.BLUETOOTH_CONNECT', 'android.permission.BLUETOOTH_ADVERTISE']
                : ['android.permission.ACCESS_FINE_LOCATION'];

            for (const permission of permissions) {
                const granted = await PermissionsAndroid.request(permission, {
                    title: '蓝牙权限请求',
                    message: '需要蓝牙权限才能扫描设备',
                    buttonNeutral: '稍后',
                    buttonNegative: '取消',
                    buttonPositive: '确定',
                });
                if (granted !== 'granted') {
                    alert('权限被拒绝,无法扫描蓝牙设备');
                    return false;
                }
            }
            return true;
        }
        return true;
    };

    // 开始扫描
    const startScan = async () => {
        const permissionsGranted = await requestPermissions();
        if (!permissionsGranted) return;

        setScanStatus('正在扫描...');
        manager.startDeviceScan(null, null, (error, device) => {
            if (error) {
                console.error('扫描出错:', error);
                setScanStatus('扫描出错');
                manager.stopDeviceScan();
                return;
            }
            // 连接的目标设备名称
            if (device.name === 'Take-73576717') {
                setDevice(device);
                setScanStatus('找到目标设备,停止扫描');
                manager.stopDeviceScan();
            }
        });
    };

    // 开始连接
    const connectDevice = () => {
        if (!device) {
            alert('未找到目标设备');
            return;
        }

        setConnectionStatus('正在连接...');
        manager.connectToDevice(device.id)
            .then((device) => {
                setConnectionStatus('已连接');
                console.log('设备连接成功:', device);
            })
            .catch((error) => {
                console.error('连接失败:', error);
                setConnectionStatus('连接失败');
            });
    };

    // 断开连接
    const disconnectDevice = () => {
        if (!device) {
            alert('未连接设备');
            return;
        }

        manager.cancelDeviceConnection(device.id)
            .then(() => {
                setConnectionStatus('未连接');
                console.log('设备已断开连接');
            })
            .catch((error) => {
                console.error('断开连接失败:', error);
            });
    };

    return (
        <SafeAreaView style={styles.container}>
            <View style={styles.buttonContainer}>
                <TouchableOpacity style={styles.button} onPress={startScan}>
                    <Text style={styles.buttonText}>开始扫描</Text>
                </TouchableOpacity>
                <TouchableOpacity style={styles.button} onPress={connectDevice}>
                    <Text style={styles.buttonText}>开始连接</Text>
                </TouchableOpacity>
                <TouchableOpacity style={styles.button} onPress={disconnectDevice}>
                    <Text style={styles.buttonText}>断开连接</Text>
                </TouchableOpacity>
            </View>
            <View style={styles.statusContainer}>
                <Text style={styles.statusText}>扫描状态: {scanStatus}</Text>
                <Text style={styles.statusText}>连接状态: {connectionStatus}</Text>
            </View>
        </SafeAreaView>
    );
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#fff',
    },
    buttonContainer: {
        flexDirection: 'row',
        justifyContent: 'space-around',
        width: '80%',
        marginBottom: 20,
    },
    button: {
        backgroundColor: '#EF6234',
        padding: 10,
        borderRadius: 5,
    },
    buttonText: {
        color: '#fff',
        fontSize: 16,
    },
    statusContainer: {
        width: '80%',
        alignItems: 'center',
    },
    statusText: {
        fontSize: 14,
        color: '#333',
        marginBottom: 5,
    },
});