React Native expo-location:如何让后台位置服务更新更频繁?

Posted

技术标签:

【中文标题】React Native expo-location:如何让后台位置服务更新更频繁?【英文标题】:React Native expo-location: How to make the background location service update more often? 【发布时间】:2021-07-19 14:11:26 【问题描述】:

我正在使用 Expo / React Native 构建一个体育应用程序,并试图找出一种在应用程序处于后台时跟踪用户位置的好方法。我已经使用 expo-location (https://docs.expo.io/versions/latest/sdk/location/#locationstartlocationupdatesasynctaskname-options) 构建了一个成功接收位置更新的解决方案,我什至设法在 EventEmitter 的帮助下将位置更新发送到 UI。

现在的问题是,Expo Location 任务会在向 UI 发送位置更新之前将位置更新延迟很长时间(例如 12 分钟)。尽管将所有相关选项都设置为零或非常小。

我很想使用 Expo Location,因为它大部分时间都在工作,但令人难以置信的是,该库似乎缺少一个选项/工具来强制后台任务足够频繁地发送更新(比如每 5 秒一次)。

如果有人能够真正让世博会后台位置足够频繁地发送更新,我将不胜感激。现在它会“在我喜欢的时候”发送更新,大约每 5 或 12 分钟一次,尽管设置了我在文档中找到的所有相关选项和参数。

我已经得出结论,世博会背景位置实际上已损坏,我应该切换到另一个位置库 (https://github.com/mauron85/react-native-background-geolocation)。但是我正在使用 Expo 管理的工作流程并且安装这个 mauron85 位置库(否则非常有希望)不起作用,因为它需要手动设置依赖项->我需要从 Expo 管理的工作流程中弹出->弹出会破坏我的项目结构一种我不知道如何解决的方法。真的很郁闷!

我的代码的相关部分:

顶部:

import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';
import EventEmitter from 'EventEmitter'

const locationEmitter = new EventEmitter();

const BACKGROUND_LOCATION_TRACKER = 'BACKGROUND_LOCATION_TRACKER'
const LOCATION_UPDATE = 'LOCATION_UPDATE'

请求位置权限后的componentDidMount:

await Location.startLocationUpdatesAsync(BACKGROUND_LOCATION_TRACKER, 
            accuracy: LocationAccuracy.BestForNavigation,
            timeInterval: 0,  // all set to 0 to make it update as often as possible!!! doesn't help
            distanceInterval: 0,
            deferredUpdatesInterval: 0, 
            deferredUpdatesDistance: 0,
            showsBackgroundLocationIndicator: true,
            foregroundService: 
                notificationTitle: 'title',
                notificationBody: 'recording',
                notificationColor: '#008000',
            ,
            // pausesUpdatesAutomatically: true,

        );

    locationEmitter.on(LOCATION_UPDATE, (locationData) => 
        console.log('locationEmitter locationUpdate fired! locationData: ', locationData);
        let coordinatesAmount = locationData.newRouteCoordinates.length - 1;
        this.setState(
            latitude: locationData.newRouteCoordinates[coordinatesAmount - 1].latitude,
            longitude: locationData.newRouteCoordinates[coordinatesAmount - 1].longitude,
            routeCoordinates: this.state.routeCoordinates.concat(locationData.newRouteCoordinates)
        )
    )

定义定位任务:

TaskManager.defineTask(BACKGROUND_LOCATION_TRACKER, async ( data, error ) => 
    if (error) 
        console.error(error);
        return;
    

    if (data) 
        const  locations  = data;
        console.log('backgroundLocationTracker received new locations: ', locations)

        // const [location] = locations;
        const locationsLength = locations.length;

        const newRouteCoordinates = [];
        // const totalNewDistance = 0.0;

        for (i = 0; i < locationsLength; i++) 
            const  latitude, longitude  = locations[i].coords;
            const tempCoords = 
                latitude,
                longitude,
            ;
            newRouteCoordinates.push(tempCoords);
            // totalNewDistance += GLOBAL.screen1.calcDistance(newRouteCoordinates[i], newRouteCoordinates[i - 1])  
        ;

        console.log('backgroundLocationTracker: latitude ', locations[locationsLength - 1].coords.latitude,
            ', longitude: ', locations[locationsLength - 1].coords.longitude, ', routeCoordinates: ', newRouteCoordinates,
            ', prevLatLng: ', newRouteCoordinates[locationsLength - 1]);

        let locationData =  newRouteCoordinates 

        locationEmitter.emit(LOCATION_UPDATE, locationData)

    

);

正如我所说,这一切都有效(!),因为我确实从后台获取位置更新到 UI。这里唯一的问题是我不知道如何让后台任务更频繁地发送位置更新!它只是持续收集大量 50 多个位置更新甚至 10 多分钟,然后才费心将它们发送到 UI!

感谢所有帮助,谢谢。

【问题讨论】:

你在这方面有没有成功。我想留在托管工作流中,因为我对去裸工作流没有足够的了解 @JeanRoux 目前没有成功。我决定暂时暂停这个项目,满足于只进行前台位置跟踪工作。我可能会在今年秋天的某个时候回到它并继续寻找解决方案。 谢谢@ajupar。似乎这里最好的选择是在没有 expo 的情况下弹出并进入反应本机,并使用像 mauron85 这样的第三方库。现在也只是坚持使用前景位置。 @JeanRoux 是的,mauron85 似乎是目前最好的库。我在尝试弹出时偶然发现了其他问题,并在 *** 和 Expo 论坛上询问了它。我在 Expo 论坛上得到了一个可能对您也有用的答案:forums.expo.dev/t/… 【参考方案1】:

我以为我也必须退出世博会,但我改变了我的选择,现在它按照我的预期更新了。 问题在于准确性,就像您的示例一样,我切换到“最适合导航”并且它起作用了。 这是我的选择,我认为您应该尝试定义一些毫秒,不要将间隔设置为 0,也不要设置距离间隔或延迟距离:

accuracy: Location.Accuracy.BestForNavigation,
            timeInterval: 1000,
            showsBackgroundLocationIndicator: true,
            foregroundService:
                notificationTitle: "Covid Tracker",
                notificationBody: "Rastreando sua localização",
                notificationColor: "#AA1111"
            ,
            deferredUpdatesInterval: 100
        

【讨论】:

以上是关于React Native expo-location:如何让后台位置服务更新更频繁?的主要内容,如果未能解决你的问题,请参考以下文章

react native 增加react-native-camera

更新 react-native-maps 以使用 create-react-native-app

react native 增加react-native-storage

React-Native 和 Expo:create-react-native-app 和 react-native init 之间的区别

什么是 react-native-cli 和 @react-native-community/cli?

React Native - 当 react-native 版本 > 0.55 时,无法通过 react-native-cli 创建新项目