Expo Background Permissions Async功能不生效如何解决
问题原因
- 权限请求顺序错误:后台定位权限必须在前台定位权限授权通过之后才能申请,你现在两个请求逻辑放在独立的
useEffect中并行执行,后台权限请求会直接失败。 - 解构赋值错误:
Location.requestBackgroundPermissionsAsync()返回的对象中权限状态字段固定为status,你直接写let { status2 }会导致status2永远为undefined,权限判断逻辑失效。 - 依赖包不兼容:
expo-permissions从Expo SDK 42开始已正式废弃,所有权限请求逻辑已迁移到对应业务模块(如定位权限全部由expo-location提供),多余导入废弃包会引发冲突。requestForegroundPermissionsAsync、requestBackgroundPermissionsAsync两个方法仅在expo-location@12.0.0及以上版本提供,若你的expo-location版本低于该值,会直接报方法不存在的错误,且expo-location版本必须和你使用的Expo SDK版本严格匹配,否则也会出现兼容问题。
- 配置缺失:后台定位权限需要在
app.json中提前配置对应平台的权限声明,否则系统会直接驳回权限请求。
修复步骤
- 卸载废弃的
expo-permissions包,执行命令:
同时删除代码中两行npm uninstall expo-permissions # 或yarn用户执行 yarn remove expo-permissionsexpo-permissions相关的导入语句。 - 修正后台权限请求的解构写法:
把let { status2 } = await Location.requestBackgroundPermissionsAsync()改为let { status: status2 } = await Location.requestBackgroundPermissionsAsync() - 调整权限请求顺序:将后台权限请求逻辑移到前台权限授权成功的分支之后,不要分两个独立的
useEffect并行执行,示例调整如下:useEffect(() => { (async () => { if (Platform.OS === 'android' && !Constants.isDevice) { setErrorMsg('Oops, this will not work on Snack in an Android emulator. Try it on your device!'); return; } // 先请求前台权限 let { status: foregroundStatus } = await Location.requestForegroundPermissionsAsync(); if (foregroundStatus !== 'granted') { setErrorMsg('Permission to access location was denied'); return; } let location = await Location.getCurrentPositionAsync({}); setLocation(location); // 前台权限获取成功后再请求后台权限 let { status: backgroundStatus } = await Location.requestBackgroundPermissionsAsync(); if (backgroundStatus !== 'granted') { setErrorMsg2('Permission to access background location was denied'); return; } let location2 = await Location.getCurrentPositionAsync({}) setLocation2(location2) })(); }, []); - 检查版本匹配:确认你的Expo SDK版本≥42,且安装的
expo-location版本和SDK版本对应,可通过执行expo install expo-location自动安装匹配版本,避免手动安装版本不兼容。 - 补充
app.json权限配置,托管工作流无需修改原生代码,直接在配置中添加以下内容即可:{ "expo": { "ios": { "infoPlist": { "NSLocationWhenInUseUsageDescription": "应用使用期间需要获取你的位置提供服务", "NSLocationAlwaysAndWhenInUseUsageDescription": "应用后台运行时需要持续获取你的位置完成轨迹追踪" } }, "android": { "permissions": [ "ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION", "ACCESS_BACKGROUND_LOCATION" ] } } }
修改完成后重新执行expo start --clear清除缓存启动即可。
内容的提问来源于stack exchange,提问作者MK_Pierce
相关产品推荐
相关产品推荐

