我有一个应用程序,我需要跟踪车辆,为此,我有一个使用expo的反应本机应用程序,但我很难在后台跟踪车辆(当应用程序最小化时)并获取此数据使用网络套接字发送到我的后端。
我的组件,没有返回,因为这部分不重要:
import AsyncStorage from "@react-native-async-storage/async-storage";
import { useNavigation } from "@react-navigation/native";
import { LinearGradient } from "expo-linear-gradient";
import React, { useEffect, useState } from "react";
import dayjs from "dayjs";
import {
KeyboardAvoidingView,
Linking,
ScrollView,
Text,
View,
} from "react-native";
import { Button } from "react-native-elements";
import Ionicons from "react-native-vector-icons/Ionicons";
import * as Location from "expo-location";
import * as TaskManager from "expo-task-manager";
import io from "socket.io-client";
import api from "../../../services/api";
import Theme from "../../../utils/globalTheme";
import styles from "./styles";
import CustomStatusBar from "../../../components/CustomStatusBar";
import DeclineButton from "../../../components/DeclineButton";
import FormButton from "../../../components/FormButton";
import FormInput from "../../../components/FormInput";
import ImageInputWithoutName from "../../../components/ImageInputWithoutName";
import Loading from "../../../components/Loading";
import ToastMessage from "../../../components/ToastMessage";
import { money } from "../../../utils/globalFunctions";
const LOCATION_TASK_NAME = "background-location-task";
let backgroundSubscription = null;
const socket = io("https://mysocketurl.com", {
autoConnect: true,
reconnection: true,
reconnectionAttempts: Infinity,
reconnectionDelay: 5000,
});
const FreightInProgress = () => {
const navigation = useNavigation();
const [position, setPosition] = useState(null);
const [userId, setUserId] = useState(null);
const [user, setUser] = useState("");
const [freight, setFreight] = useState();
const [aduanas, setAduanas] = useState([]);
const [loading, setLoading] = useState(true);
const [inProgress, setInProgress] = useState(false);
const [canhotoPhoto, setCanhotoPhoto] = useState(null);
useEffect(() => {
const requestPermissions = async () => {
const { granted } = await Location.requestBackgroundPermissionsAsync();
if (!granted) {
console.log("background location tracking not granted");
return;
}
};
requestPermissions();
AsyncStorage.getItem("userId").then((userId) => {
const id = JSON.parse(userId);
setUserId(id);
});
AsyncStorage.getItem("user").then((user) => {
const userJson = JSON.parse(user);
setUser(userJson.nome);
});
}, []);
TaskManager.defineTask(
"background-location-task",
async ({ data, error }) => {
if (error) {
console.error(error);
return;
}
if (data) {
const { locations } = data;
const location = locations[0];
setPosition(location);
if (location) {
socket.emit("coords", {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
usuario_id: userId,
userName: user,
freight: freight,
});
}
}
}
);
const finishFreight = async () => {
if (canhotoPhoto != null) {
try {
const body = {
canhoto: canhotoPhoto,
};
const resp = await api.put(
`/freights/proofOfDelivery/${freight.id}`,
body
);
if (resp.status == 200) {
await api.put(`/freights/${freight.id}/status`, {
status: "Concluído",
});
stopBackgroundUpdate();
setCanhotoPhoto(null);
navigation.navigate("Perfil");
ToastMessage({
type: "success",
title: "Sucesso!",
message: "Frete concluído!",
});
} else {
ToastMessage({
type: "error",
title: "Erro!",
message: "Erro ao enviar canhoto!",
});
}
} catch (error) {
console.log(error);
ToastMessage({
type: "error",
title: "Erro ao iniciar frete!",
message: "Tente novamente!",
});
}
} else if (canhotoPhoto == null) {
ToastMessage({
type: "error",
title: "Erro!",
message: "Favor mandar canhoto!",
});
}
};
const stopBackgroundUpdate = () => {
backgroundSubscription?.remove();
setPosition(null);
};
const startBackground = async () => {
const { granted } = await Location.requestBackgroundPermissionsAsync();
if (!granted) {
console.log("background location tracking not granted");
return;
}
backgroundSubscription?.remove();
backgroundSubscription = await Location.startLocationUpdatesAsync(
"background-location-task",
{
accuracy: Location.Accuracy.BestForNavigation,
}
);
};
const getFreightById = async (driverId) => {
try {
const resp = await api.get(`/drivers/${driverId}/withFreight`);
console.log(resp.data);
if (resp.data.status == 1) {
setInProgress(true);
} else {
setInProgress(false);
}
setFreight(resp.data);
setAduanas(resp.data.Frete_Endereco.slice(1, -1));
setLoading(false);
} catch (error) {
console.log(error);
setFreight(undefined);
setInProgress(false);
setLoading(false);
}
};
const handleStart = async () => {
try {
await api.put(`/freights/${freight.id}/status`, {
status: "Andamento",
});
setInProgress(true);
startBackground();
ToastMessage({
type: "success",
title: "Sucesso!",
message: "Frete iniciado!",
});
} catch (error) {
console.log(error);
ToastMessage({
type: "error",
title: "Erro ao iniciar frete!",
message: "Tente novamente!",
});
}
};
const handleDeleteApplication = async () => {
try {
const body = {
motorista_id: driverId,
};
const resp = await api.put(`/freights/application/exclude/${id}`, body);
ToastMessage({
type: "success",
title: "Sucesso!",
message: resp.data.message,
});
navigation.navigate("Candidaturas");
} catch (error) {
ToastMessage({
type: "error",
title: "Erro!",
message: error.response.data.message,
});
}
};
const OpenURLButton = ({ url, title }) => {
const handlePress = async () => {
const supported = await Linking.canOpenURL(url);
if (supported) {
await Linking.openURL(url);
} else {
Alert.alert(`Não foi possível abrir a URL.`);
}
};
return (
<Button
onPress={handlePress}
title={title}
buttonStyle={styles.linkButton}
titleStyle={styles.linkButtonTitle}
/>
);
};
useEffect(() => {
navigation.addListener("focus", async () => {
setLoading(true);
await AsyncStorage.getItem("user").then((user) => {
const userJson = JSON.parse(user);
getFreightById(userJson.id);
});
});
}, []);
return ("... my component here")
};
export default FreightInProgress;
我在上面尝试了这段代码,在前台,位置效果很好
我在这方面遇到了其他麻烦(这就是我正在搜索该主题的原因),但您的 TaskManager.defineTask 应该在全局范围内声明,在 FreightInProcess 之外。希望这会有所帮助,尽管该帖子很旧......