@Rai1

Как решить нестабильную работу task manager expo?

Всем привет. Писал на expo геотрекер. Столкнулся с такой проблемой: он шлет данные в фоне, все хорошо, но после некоторого времени просто их перестает слать, на минут 10, и снова как ни в чем не бывало начинает. Хотелось бы узнать, в чем может быть причина? Update режим энергосбережения выключен
const LOCATION_TASK_NAME = "LOCATION_TASK_NAME"

TaskManager.defineTask(LOCATION_TASK_NAME, async (res) => {

    if (res.error) {
        return
    }

    if (res.data) {
        const {locations} = res.data
        const location = locations[0]
        const storageUserId = await AsyncStorage.getItem("userId")
        const storageCoordsArray = await AsyncStorage.getItem("coordsArray")

        if (location && storageUserId) {
            const date = new Date()

            const currentCoords = {
                lat: location.coords.latitude,
                lng: location.coords.longitude,
                date: date.toString(),
            }

            if (storageCoordsArray) {
                const length = parseJsonString(storageCoordsArray).length
                // проверяем длину массива что бы не переполнить сторедж
                if (length >= 1000) {
                    const result = parseJsonString(storageCoordsArray)
                    result.shift()
                    result.push(currentCoords)
                    await AsyncStorage.setItem("coordsArray", JSON.stringify(result))
                } else {
                    const result = parseJsonString(storageCoordsArray)
                    result.push(currentCoords)
                    await AsyncStorage.setItem("coordsArray", JSON.stringify(result))
                }
            } else {
                const result = []
                result.push(currentCoords)
                await AsyncStorage.setItem("coordsArray", JSON.stringify(result))
            }

            if (storageCoordsArray) {
                const bodyRequest = parseJsonString(storageCoordsArray)

                if (bodyRequest.length % 10 === 0) {
                    try {
                        const bodyFormData = {
                            userId: storageUserId,
                            data: bodyRequest
                        }

                        const response = await axios.post(`${CONFIG.BASE_URL}/api/opp/geo/`, bodyFormData)
                        const data = response.data
                        if (data.status === "success") {
                            await AsyncStorage.removeItem("coordsArray")
                        }
                    } catch (err) {
                        console.log(err)
                    }
                }
            }
        }
    }
})

export const ManagerLocation = () => {
    const global = useSelector((state) => state.global)
    const navigation = useNavigation()
    const isFocused = useIsFocused()
    const [start, setStart] = useState(false)
    const [noticeShow, setNoticeShow] = useState(false)
    const [isConnected, setIsConnected] = useState(true)

    const requestPermissions = async () => {
        const foreground = await Location.requestForegroundPermissionsAsync()
        if (foreground.granted) await Location.requestBackgroundPermissionsAsync()
    }

    const startBackgroundUpdate = async () => {

        try {
            const {granted} = await Location.getBackgroundPermissionsAsync()
            if (!granted) {
                return
            }

            const isTaskDefined = await TaskManager.isTaskDefined(LOCATION_TASK_NAME)

            if (!isTaskDefined) {
                return
            }

            const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME)
            if (hasStarted) {
                return
            }

            await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
                accuracy: Location.Accuracy.BestForNavigation,
                timeInterval: 2000,
                distanceInterval: 3,
                pausesUpdatesAutomatically: true,
                showsBackgroundLocationIndicator: true,
                deferredUpdatesDistance: 0,
                deferredUpdatesInterval: 0,
                activityType: Location.ActivityType.AutomotiveNavigation,
                showsBackgroundLocationIndicator: true,
                foregroundService: {
                    notificationTitle: "Геолокация",
                    notificationBody: "Мы отслеживаем вашу геолокацию в фоновом режиме",
                    notificationColor: "#ffce52",
                    killServiceOnDestroy: false,
                },
            });

            setStart(true)

            const unsubscribe = NetInfo.addEventListener((state) => {
                setIsConnected(state.isConnected)
            })

            if (!isConnected) {
                await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME)
                await startBackgroundUpdate()
                setStart(false)
            }

            return () => {
                Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME)
                unsubscribe()
            }
        } catch (error) {
            console.log(error)
        }
    }

    const stopBackgroundUpdate = async () => {
        const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME)
        if (hasStarted) {
            await Location.stopLocationUpdatesAsync(LOCATION_TASK_NAME)

            setStart(false)

            const storageCoordsArray = await AsyncStorage.getItem("coordsArray")
            const storageUserId = await AsyncStorage.getItem("userId")
            if (storageCoordsArray && storageUserId) {
                try {
                    const bodyRequest = parseJsonString(storageCoordsArray)

                    const bodyFormData = {
                        userId: storageUserId,
                        data: bodyRequest
                    }

                    const response = await axios.post(`${CONFIG.BASE_URL}/api/opp/geo/`, bodyFormData)
                    const data = response.data
                    if (data.status === "success") {
                        await AsyncStorage.removeItem("coordsArray")
                    }
                } catch (err) {
                    console.log(err)
                }
            }
        }
    }

    const press = async () => {
        if (start) {
            await stopBackgroundUpdate()
        } else {
            const headers = await getHeadersLogin()
            const response = await axios.get(`${CONFIG.BASE_URL}/api/opp/geo/notice/?userId=${global.userId}`, {headers})
            const data = response.data

            if (data) {
                if (data.show) {
                    navigation.navigate("PopupOppManager")
                    setNoticeShow(true)
                } else {
                    startGeo()
                }
            }
        }
    }

    const startGeo = async () => {
        await requestPermissions()
        await startBackgroundUpdate()
    }

    useEffect(() => {
        if (start) {
            startGeo()
        }
    }, [start, isConnected])

    useEffect(() => {
        const checkLocationStatus = async () => {
            const hasStarted = await Location.hasStartedLocationUpdatesAsync(LOCATION_TASK_NAME)
            if (hasStarted) {
                setStart(true)
            }
        }
        checkLocationStatus()
    }, [])

    useEffect(() => {
        if (isFocused && noticeShow) {
            startGeo()
            setNoticeShow(false)
        }
    }, [isFocused])

    return (
        <View style={styles.container}>
            <AppButton
                onPress={press}
                text={start ? "Гео данные собираются" : "Гео данные не собираются"}
                textSmall={start ? "Выключить сбор гео данных" : "Включить сбор гео данных"}
                style={{
                    ...styles.button,
                    backgroundColor: THEME.COLORS[start ? "GREEN" : "RED_2"]
                }}
            />
        </View>
    )
}
  • Вопрос задан
  • 24 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы