Expo Location watchHeadingAsync无法在Android上运行



我正在编写一个应用程序,要求我跟踪用户设备的标题。在iOS上一切都很好,但在Android上,标题非常不稳定,经常在两个值之间闪烁:

Log output:
angle: 17.43
angle: 358.7
angle: 17.43
angle: 358.7

这是我的代码:

onVidLoad(){
Location.watchHeadingAsync(this.onHeadingUpdate).then((v) => {
this.ang_listener = v;
});
}
onHeadingUpdate = (h) => {
var angle = h.trueHeading;
angle -= 180;
angle *= -1;
angle += 180;
console.log("angle:", angle);
}

提前谢谢。

编辑:每次应用程序启动时,我都在使用Location.requestForegroundPermissionsAsync,所以问题不在于我没有正确的权限

我在Android上的Location.watchHeadingAsync也遇到过同样的问题。航向在一定程度上起作用,但非常不稳定,而且往往会跳来跳去。

作为替代方案,我建议使用DeviceMotion在Android设备上获取设备的标题。

对于Android:

您可以使用expo传感器的DeviceMotion来获得更可靠的航向数据。下面是一个示例代码片段:

import { DeviceMotion } from 'expo-sensors';
// ...
const [deviceMotionHeading, setDeviceMotionHeading] = useState(null);
useEffect(() => {
let deviceMotionSubscription = DeviceMotion.addListener(({ rotation }) => {
// Extract rotation data
const { alpha } = rotation;
// Calculate heading
let calculatedHeading = 360 - (alpha * 180 / Math.PI);
if (calculatedHeading < 0) {
calculatedHeading += 360;
}
if (calculatedHeading > 360) {
calculatedHeading -= 360;
}
setDeviceMotionHeading(calculatedHeading);
});
return () => {
deviceMotionSubscription && deviceMotionSubscription.remove();
};
}, []);

对于iOS:

Location.watchHeadingAsync在iOS上运行可靠。这里有一个例子:

import * as Location from 'expo-location';
// ...
const [locationHeading, setLocationHeading] = useState(null);
useEffect(() => {
(async () => {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== 'granted') {
console.log('Permission to access location was denied');
return;
}
let locationSubscription = await Location.watchHeadingAsync((locationHeading) => {
setLocationHeading(locationHeading.trueHeading);
});
return () => {
locationSubscription && locationSubscription.remove();
};
})();
}, []);

您可以调整更新间隔以平滑标题更新,如:

useEffect(() => {
DeviceMotion.setUpdateInterval(16); // Added this line
let deviceMotionSubscription = DeviceMotion.addListener(({ rotation }) => {
// Extract rotation data
const { alpha } = rotation;

对于16毫秒,即0.016秒:

频率(Hz(=1/(时间间隔(秒((

频率(Hz(=1/0.016≈62.5 Hz

您可能还希望设置固定的小数位数,以减少重新渲染的频率,从而提高UI的性能。例如,您可以将标题四舍五入到小数点后一位,如下所示:

setDeviceMotionHeading(calculatedHeading.toFixed(1));

最新更新