反应本机博览会背景位置不起作用



我是反应原生的新手,我正在使用expo,如果应用程序在后台或被杀,我正在尝试获取用户位置。我使用了任务管理器,但我不知道为什么它不起作用。当应用程序在前台运行时,它工作正常,但是当应用程序在后台或被杀时,它不会给我位置。

我正在使用"从展览位置的位置"


const LOCATION_TASK_NAME = "background-location-task";
componentDidMount = async () => {
this._getLocationAsync();
};
_getLocationAsync = async () => {
try {
//ask permission of user for location
let { status } = await Permissions.askAsync(Permissions.LOCATION);
//check the location setting
const permissionStaatus = await Location.getProviderStatusAsync();
const newStatus = permissionStaatus.locationServicesEnabled;
//if phone location is disabled
if (!newStatus) {
const { navigation } = this.props;
Alert.alert(
"Error",
"Please Turn On you'r Location",
[
{
text: "OK",
onPress: this.openSetting
}
],
{ cancelable: false }
);
}
// if location setting is enabled
else {
//if status is granted or not
if (status !== "granted") {
this.setState({
errorMessage: "Permission to access location was denied"
});
return;
} else {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
timeInterval: 3000,
distanceInterval: 1
});
}
}
} catch (error) {
let status = await Location.getProviderStatusAsync();
if (!status.locationServiceEnabled) {
const { navigation } = this.props;
navigation.navigate("Site");
// console.log(error);
}
}
};

TaskManager.defineTask(LOCATION_TASK_NAME, async ({ data, error }) => {
if (error) {
// Error occurred - check `error.message` for more details.
return;
}
if (data) {
const { locations } = data;
const location = locations.map(location => {
let newLocation = Location.reverseGeocodeAsync(location.coords)
.then(data => {
data.map(location => {
axios.post(
"http://192.168.0.1/api/account/saveUserLocation",
location
);
})
})
})
}
});

您需要为 android 启用粘滞通知,较新版本的 android 操作系统的行为有所不同。自安卓(8.0)

您必须使用粘性通知才能使您的应用保持在前台。 您需要将这些选项传递给startLocationUpdatesAsync

foregroundService: {
notificationTitle: 'Your title',
notificationBody: 'Notification Body'
},
pausesUpdatesAutomatically: false,
}

pausesUpdatesAutomatically适用于 IOS,如果您希望您的应用程序在被杀死时重新启动。

UPDTE任务管理器现在也适用于裸博会应用程序,从 sdk v37

当应用程序位于应用程序background上时,您无法运行ajaxTaskManager是在存储库中存储location。因此,如果您想在应用程序死机时获得location,请尝试更新location

应用.js

TaskManager.defineTask(LOCATION_TASK_NAME, async ({data, error}) => {
if(error){
return;
}
if(data){
try{
const { locations } = data;
console.log("locations :" + locations);
await AsyncStorage.setItem('newlocation',data); //maybe it work
} catch(error){
console.log(error);
}
}

更新位置

updatedLocation = async() => {
const { status } = await Permissions.askAsync(Permissions.LOCATION);
let isRegistered = await 
TaskManager.isTaskRegisteredAsync(LOCATION_TASK_NAME);
if(isRegistered && status=='granted'){
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.High,
timeInterval: 2500,
distanceInterval: 5,
showsBackgroundLocationIndicator: false
});
}
... more code
}
...
// get localstorage data
_retrieveData = async () => {
try {
const value = await AsyncStorage.getItem('newlocation');
if (value !== null) {
// We have data!!
console.log(value);
}
} catch (error) {
// Error retrieving data
}
};

我使用了startLocationUpdatesAsync方法的foregroundService选项,如文档中所述:

使用此选项可将位置服务置于前台状态,这将使后台的位置更新与前台状态一样频繁。缺点是,它需要粘性通知,因此用户将意识到您的应用正在运行并消耗更多资源,即使后台也是如此。(自安卓 8.0 起可用)

这是我的代码上的样子:

Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, { 
accuracy: Location.Accuracy.BestForNavigation,
timeInterval: LOCATION_TIME_INTERVAL,
distanceInterval: LOCATION_DISTANCE_INTERVAL,
foregroundService: {
notificationTitle: LOCATION_TITLE,
notificationBody: LOCATION_SUBTITLE
}
});

最新更新