应用程序运行良好已有一段时间,但现在它没有提示用户获得定位权限,这导致使用定位的功能失败。在运行expo-go的模拟器和物理设备上,都会提示用户对位置数据授予权限。(iOS和Android(它需要的所有其他权限(推送、相机和日历(
export default function CheckIn(props) {
const { todayEvents } = useSelector(({ checkin }) => checkin);
const [venueIdd, setVenueId] = useState(0);
const [modalVisible, setModalVisible] = useState(false);
const [status, setStatus] = useState(null);
const [backgroundLocationPermission, setBackgroundLocationPermission] =
useState(null);
const dispatch = useDispatch();
TaskManager.defineTask("updateLocation", ({ data: { locations }, error }) => {
if (error) {
return;
}
dispatch(sendBackgroundLocation(locations[0].coords, venueIdd));
});
async function registerBackgroundFetchAsync() {
return BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, {
minimumInterval: 60 * 15, // 15 minutes
stopOnTerminate: false, // android only,
startOnBoot: true, // android only
});
}
async function unregisterBackgroundFetchAsync() {
return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK);
}
React.useEffect(() => {
dispatch(getTodaysEvents());
const askPermission = async () => {
let getForeground = await Location.getForegroundPermissionsAsync();
if (getForeground.status !== "granted") {
let { status } = await Location.requestForegroundPermissionsAsync();
if (status !== "granted") {
Alert.alert("Permission to access location was denied");
return;
} else {
let backgroundPermissions =
await Location.requestBackgroundPermissionsAsync();
if (backgroundPermissions.status == "granted") {
await AsyncStorage.setItem("background_permission", "true");
}
}
}
};
askPermission();
}, []);
const checkIn = async (index) => {
let temp = [...todayEvents];
temp[index].isCheckedIn = true;
setVenueId(temp[index].venueId);
const backgroundStatus = await AsyncStorage.getItem(
"background_permission"
);
// if (backgroundStatus !== null) {
Location.startLocationUpdatesAsync("updateLocation", {
timeInterval: 120,
distanceInterval: 0.01,
foregroundService: {
notificationTitle: "Company title",
notificationBody:
"Information in body",
},
accuracy: Location.Accuracy.Highest,
}).then((response) => {
// console.log("RESPONSE LOCATION", response);
});
// }
setTimeout(() => {
const stopped = Location.stopLocationUpdatesAsync("updateLocation");
}, 43200000);
let { coords } = await Location.getCurrentPositionAsync();
dispatch(userCheckIn({ lat: coords.latitude, long: coords.longitude }));
};
const checkOut = async (index) => {
const stopped = Location.stopLocationUpdatesAsync("updateLocation");
let temp = todayEvents;
temp[index].isCheckedIn = false;
//dispatch(userCheckOut()); // This is what I commented out
// And the two rows below is added
let { coords } = await Location.getCurrentPositionAsync();
dispatch(userCheckOut({ lat: coords.latitude, long: coords.longitude }));
};
const review = (index, value) => {
setModalVisible(true);
setTimeout(() => {
setModalVisible(false);
setTimeout(() => {
props.navigation.goBack();
}, 300);
}, 1500);
let temp = todayEvents;
temp[index].review = value;
dispatch(giveEventFeedBack(temp[index]));
};
从app.json
定义了以下iOS位置权限:
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
对于Android:
ACCESS_BACKGROUND_LOCATION
ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
有一种情况,用户最近为该权限选择了NEVER ASK AGAIN
选项。下次应用程序尝试请求时,请求会以denied
状态静默解决,而不会启动请求权限弹出模式。
如果是这种情况,应用程序可以强制用户在应用程序设置中手动授予权限
你可以像一样处理这种情况
const permission = await Location.getForegroundPermissionsAsync();
// Detect if you can request this permission again
if (!permission.canAskAgain || permission.status === "denied") {
/**
* Code to open device setting then the user can manually grant the app
* that permission
*/
Linking.openSettings();
} else {
if (permission.status === "granted") {
// Your actually code require this permission
}
}
虽然上面的解决方案不起作用,请在Expo SDK 44中查看这个正在进行的问题https://github.com/expo/expo/issues/15273