提问人:Saw 提问时间:8/28/2023 最后编辑:Saw 更新时间:9/6/2023 访问量:116
使用“展览位置”查找后台位置权限错误
Using Expo Location to find background location permissions error
问:
我正在尝试使用 expo-location 和 expo-task-manager 在应用程序处于前台和后台时查找用户位置。我正在使用 expo 编译代码而不使用 Xcode。问题是我提供的代码给了我两个错误:
[Unhandled promise rejection: Error: One of the `NSLocation*UsageDescription` keys must be present in Info.plist to be able to use geolocation.]
at node_modules\@babel\runtime\helpers\construct.js:null in <global>
at node_modules\@babel\runtime\helpers\wrapNativeSuper.js:null in _wrapNativeSuper
- ... 3 more stack frames from framework internals
和:
[Unhandled promise rejection: Error: Background Location has not been configured. To enable it, add `location` to `UIBackgroundModes` in Info.plist file.]
at node_modules\@babel\runtime\helpers\construct.js:null in <global>
at node_modules\@babel\runtime\helpers\wrapNativeSuper.js:null in _wrapNativeSuper
- ... 3 more stack frames from framework internals
这些错误是指我的App.json中的 infoPlist 设置:
"infoPlist": {
"UIBackgroundModes": ["location"],
"NSLocationWhenInUseUsageDescription": "To allow the user to start recording a run...",
"NSLocationAlwaysUsageDescription": "To allow the distance to be measured even when the phone is turned off"
"NSLocationAlwaysAndWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to use your location to track your runs"
}
即使明确设置了 UIBackgroundModes 以及 NSLocationWhenInUseUsageDescription 和 NSLocationAlwaysUsageDescription,这些错误仍会出现。
正在运行的代码:
App.js:
import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import UserLocation from "./UserLocation"
export default function App() {
return (
<View style={styles.container}>
<UserLocation />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
用户位置.js:
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import * as Location from 'expo-location';
import * as TaskManager from 'expo-task-manager';
const LOCATION_TRACKING = 'location-tracking';
var l1;
var l2;
export default function UserLocation() {
const [locationStarted, setLocationStarted] = React.useState(false);
const startLocationTracking = async () => {
await Location.startLocationUpdatesAsync(LOCATION_TRACKING, {
accuracy: Location.Accuracy.Highest,
timeInterval: 5000,
distanceInterval: 0,
});
const hasStarted = await Location.hasStartedLocationUpdatesAsync(
LOCATION_TRACKING
);
setLocationStarted(hasStarted);
console.log('tracking started?', hasStarted);
};
React.useEffect(() => {
const config = async () => {
let resf = await Location.requestForegroundPermissionsAsync();
let resb = await Location.requestBackgroundPermissionsAsync();
if (resf.status != 'granted' && resb.status !== 'granted') {
console.log('Permission to access location was denied');
} else {
console.log('Permission to access location granted');
}
};
config();
}, []);
const startLocation = () => {
startLocationTracking();
}
const stopLocation = () => {
setLocationStarted(false);
TaskManager.isTaskRegisteredAsync(LOCATION_TRACKING)
.then((tracking) => {
if (tracking) {
Location.stopLocationUpdatesAsync(LOCATION_TRACKING);
}
})
}
return (
<View>
{locationStarted ?
<TouchableOpacity onPress={stopLocation}>
<Text style={styles.btnText}>Stop Tracking</Text>
</TouchableOpacity>
:
<TouchableOpacity onPress={startLocation}>
<Text style={styles.btnText}>Start Tracking</Text>
</TouchableOpacity>
}
</View>
);
}
const styles = StyleSheet.create({
btnText: {
fontSize: 20,
backgroundColor: 'green',
color: 'white',
paddingHorizontal: 30,
paddingVertical: 10,
borderRadius: 5,
marginTop: 10,
},
});
TaskManager.defineTask(LOCATION_TRACKING, async ({ data, error }) => {
if (error) {
console.log('LOCATION_TRACKING task ERROR:', error);
return;
}
if (data) {
const { locations } = data;
let lat = locations[0].coords.latitude;
let long = locations[0].coords.longitude;
l1 = lat;
l2 = long;
console.log(
`${new Date(Date.now()).toLocaleString()}: ${lat},${long}`
);
}
});
App.js 的完整版本:
{
"expo": {
"name": "FinalHopefully",
"slug": "FinalHopefully",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true,
"infoPlist": {
"UIBackgroundModes": ["location"],
"NSLocationWhenInUseUsageDescription": "To allow the user to start recording a run...",
"NSLocationAlwaysUsageDescription": "To allow the distance to be measured even when the phone is turned off"
"NSLocationAlwaysAndWhenInUseUsageDescription": "Allow $(PRODUCT_NAME) to use your location to track your runs"
}
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
答:
0赞
Gabriel Donadel Dall'Agnol
9/6/2023
#1
如果使用的是 expo-dev-client 和 EAS,则必须在进行这些更改后重新生成应用,如果要在本地生成,则需要运行以重新生成 iOS 文件并更新 Info.plistnpx expo prebuild --clean -p ios
评论
NSLocationAlwaysandWhenInUseUsageDescription