我正在尝试使用打字稿和react-native-ble-plx lib将我的信标与android平板电脑连接,但是当我在startDeviceScan()中提供特定的有效UUID作为道具时,它不起作用。 当 UUID 属性为空时它起作用...... 我应该更改 beacon 的默认 txPower 吗?当我使用 beacon 应用程序检查 txPower 时,它是 40。
import React, { useEffect, useRef, useState } from 'react';
import { PermissionsAndroid, Platform, Text, View } from 'react-native';
import { BleManager, Device } from 'react-native-ble-plx';
const BeaconDistanceTracker = () => {
const [beaconDistance, setBeaconDistance] = useState<number | null>(null);
const [connected, setConnected] = useState<boolean>(false); // 연결 상태 관리
const manager = useRef(new BleManager()).current; //블루투스 객체 생성 및 현재 상태 추적
useEffect(() => {
//블루투스 관련 권한 요청
const requestPermissions = async () => {
const fineLocationGranted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
const coarseLocationGranted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION);
console.log('FineLocationGranted:', fineLocationGranted);
console.log('CoarseLocationGranted:', coarseLocationGranted);
if (Platform.OS === 'android' && Platform.Version >= 31) {
const bluetoothScanGranted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN);
console.log('BluetoothScanGranted:', bluetoothScanGranted);
const bluetoothConnectGranted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT);
console.log('BluetoothConnectGranted:', bluetoothConnectGranted);
}
};
//RSSI 기반 거리 계산
const calculateDistance = (rssi: number, txPower: number): number => {
if (rssi === 0) return -1.0;
const ratio = rssi / txPower;
if (ratio < 1.0) return Math.pow(10, (txPower - rssi) / (10 * 1));
return (0.89976) * Math.pow(10, (txPower - rssi) / (10 * 2));
};
//RSSI값 실시간 업데이트
const handleUpdateRSSI = async (device: Device) => {
const { rssi } = device;
if (rssi !== null) {
const txPower = 0;
const distance = calculateDistance(rssi, txPower);
setBeaconDistance(distance);
console.log('RSSI:', rssi, '거리:', distance.toFixed(2), '미터');
// 연결 상태가 false인 경우에만 연결 시도
if (!connected) {
try {
console.log('디바이스 연결 시도 중...'); // 연결 시도 로그
// 디바이스 연결 시도
await device.connect();
await new Promise(resolve => setTimeout(resolve, 3000)); // 3초 대기
const isConnected = await device.isConnected(); // 연결 상태 확인
setConnected(isConnected); //연결 상태 업데이트
//연결 상태 로그 출력
if (isConnected) {
console.log('디바이스가 연결되었습니다.');
} else {
console.log('디바이스 연결에 실패했습니다.');
}
} catch (error) {
console.log('디바이스 연결 중 오류 발생:', error);
}
}
} else {
console.log('RSSI 값이 null입니다.');
}
};
//비콘 추적 시작
const startScanning = () => {
const beaconUUID = 'e2c56db5-dffb-48d2-b060-d0f5a71096e0'; // 비콘의 UUID로 변경하세요.
manager.startDeviceScan(
//UUIDs: UUID[] | null
[beaconUUID],
// options: ScanOptions | null,
null,
// listener: (error: BleError | null, scannedDevice: Device | null) => void
(error, device) => {
if (error) {
console.error(error);
return;
}
if (device) {
console.log('Device Detected:', device);
handleUpdateRSSI(device);
}else{
console.log('Failed to find Device while scanning');
}
}
)};
requestPermissions().then(() => {
startScanning();
});
return () => {
manager.stopDeviceScan();
};
}, [manager, connected]); // connected 상태를 의존성 배열에 추가
useEffect(() => {
console.log('현재 비콘과의 거리:', beaconDistance);
}, [beaconDistance]);
useEffect(() => {
const subscription = manager.onStateChange((state) => {
console.log('bleManger State:',state);
})
return () => {
subscription.remove();
}
},[])
return (
<View>
<Text style={{ color: 'white' }}>
비콘과의 거리: {beaconDistance !== null ? `${beaconDistance.toFixed(2)} 미터` : '측정 중...'}
</Text>
<Text style={{ color: 'white' }}>
연결 상태: {connected ? '연결됨' : '연결되지 않음'}
</Text>
</View>
);
};
export default BeaconDistanceTracker;
我想检测设备,并持续观察RSSI,这样我就可以使用RSSI计算距离。
代码中使用的react-native-ble-plx模块将无法工作。 它并非旨在检测 Minew E7 或其他 iBeacon 兼容的 BLE 信标。 它旨在与更通用的蓝牙外设配合使用,这些外设使用较低级别的方案来扫描和检测其广告。 您使用此模块扫描的UUID不是iBeacon UUID,而是较低级别的蓝牙GATT服务UUID,是完全不同的概念。
相反,尝试使用此模块,按照说明开始 iBeacon 测距。 设置起来会更容易,您可以使用代码中显示的 UUID 来查找信标。
注意:虽然理论上可以使用react-native-ble-plx编写代码来检测你的信标,但这将很困难并且需要大量代码,因为你基本上是从头开始编写自己的信标检测模块。