Expo Location 完整指南:React Native 定位从权限到后台避坑

Expo Location 完整指南:React Native 定位从权限到后台避坑 Expo Location 完整指南React Native 定位从权限到后台避坑【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expoExpo Location 是 Expo 开源框架中专职位置服务的模块一个expo-location依赖就能在 Android、iOS 和 Web 上完成 React Native 定位获取、权限配置、实时订阅与后台追踪。照着这篇写前台定位到地理围栏都能一次跑通。门店打卡、导航与跑步轨迹三个位置场景先不急着写代码看看位置能力到底在什么场景下被需要。门店打卡销售 App 要求到店才能提交订单。你只需要一次高精度的坐标再和门店围栏比对判断用户是否在场。这里的核心是getCurrentPositionAsync加一次区域判断。实时导航打车或户外徒步 App 需要持续拿到用户坐标刷新地图上的蓝点。这里要用订阅式的watchPositionAsync按时间和距离双条件节流避免每秒都刷一次 UI。后台跑步轨迹跑步 App 熄屏后必须继续记录轨迹。这要求后台定位权限加上 TaskManager 后台任务还要考虑电量。它是整套能力里约束最多的一环权限配置没做对就完全收不到数据。三个场景对应三种 API 形态单次获取、前台订阅、后台任务。下面按装好 → 配权限 → 用 API → 验证 → 省电量 → 排错的顺序走一遍。环境准备与权限配置 3 步到位第一步装依赖npx expo install expo-location第二步在app.json中声明权限文案和后台开关。iOS 文案不写系统弹窗会直接显示英文默认值Android 后台定位必须显式开启否则预构建不会写入对应权限{ expo: { plugins: [ [ expo-location, { locationWhenInUsePermission: 用于记录你的运动轨迹, isIosBackgroundLocationEnabled: true, isAndroidBackgroundLocationEnabled: true } ] ] } }第三步理解两个平台权限模型的差异这是后面一切排错的基础权限维度iOSAndroid前台定位When In Use弹窗可选允许一次一次弹窗授予精确定位后台定位Always且需在 Info.plist 开启UIBackgroundModes需ACCESS_BACKGROUND_LOCATION且先有前台授权运行载体后台定位必须在开发构建Development Build中运行后台定位依赖前台服务Expo Go 里不可用申请顺序先前台后后台允许一次后再请求后台会静默失败先申请前台再申请后台一个建议贯穿始终采用渐进式申请。先用requestForegroundPermissionsAsync拿到前台权限让核心功能跑起来等用户真正触发后台功能比如点开始跑步时再请求后台权限。iOS 上如果用户选了允许一次第二次后台请求会直接返回 denied 而不是弹框所以应用必须能只靠前台权限降级运行。核心能力三步走第一步一行代码获取当前位置原理很简单先申请前台权限再用getCurrentPositionAsync发起一次定位模块内部会根据精度档位选择 GPS、Wi-Fi 或基站。const { status } await Location.requestForegroundPermissionsAsync(); if (status ! granted) { // 引导用户去系统设置开启 return; } const position await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.High, }); console.log(position.coords.latitude, position.coords.longitude);易踩的坑在室内用High精度时首次冷启动定位可能卡住好几秒才出结果。如果业务只要求大致在哪改用Accuracy.Low或者直接调getLastKnownPositionAsync拿系统缓存的上次定位毫秒级返回。第二步订阅实时位置更新watchPositionAsync会返回一个订阅对象回调里收到每次更新remove()之后才真正停止监听。它只在前台生效App 退到后台就停。const sub await Location.watchPositionAsync( { accuracy: Location.Accuracy.Balanced, timeInterval: 5000, distanceInterval: 10 }, (loc) console.log(new position, loc.coords.latitude) ); // 组件卸载时记得 sub.remove();易踩的坑忘了remove()。监听器不释放坐标会一直往回调里灌既耗电又可能触发重复渲染。把它放进useEffect的清理函数里最稳妥。第三步地理围栏两步接入地理围栏把判断进没进圈这件事交给系统应用休眠时也能收到进/出场事件回调通过 TaskManager 任务派发这是它和省电的关键。TaskManager.defineTask(GEOFENCE, ({ data, error }) { if (error) return; const { eventType, region } data; // eventType 为 GeofencingEventType.Enter / Exit console.log(eventType, region.identifier); }); await Location.startGeofencingAsync(GEOFENCE, [ { identifier: store-001, latitude: 39.9, longitude: 116.4, radius: 300 }, ]);易踩的坑任务必须用TaskManager.defineTask在模块顶层作用域定义放在函数体里注册会丢失。另外注意平台上限iOS 同时最多监控 20 个区域Android 最多 100 个围栏超限要自行做区域合并或分批。后台定位同一套思路的延伸跑步轨迹这类需求用startLocationUpdatesAsync(taskName, options)启动坐标数组通过后台任务的data.locations批量送达结束时调stopLocationUpdatesAsync(taskName)。两个前提别忘任务同样要在顶层用defineTask注册Expo Go 不支持后台定位Android 上还得把配置里的isAndroidForegroundServiceEnabled打开。想验证是否生效用hasStartedLocationUpdatesAsync查一下状态。测试与验证清单模拟器与真机模拟器调试前先做一遍环境自检很多收不到位置其实只是模拟位置没开。Android 模拟器启动模拟器后进入Settings → Location打开Use locationAndroid 12 关闭Improve Location Accuracy关掉 Wi-Fi 定位只用模拟 GPS 数据用模拟器扩展面板发送 GPS 坐标确认应用能收到iOS 模拟器打开Features → Location选择任意非 None 的位置想模拟移动轨迹时选 Custom Location逐步改变坐标真机验证首次安装后完整走一遍权限弹窗别直接点拒绝否则要清数据重来到系统设置里确认位置权限是始终允许测试后台功能时Android 真机注意厂商杀后台行为把应用加入自启动/电池白名单否则后台任务可能被系统直接杀掉后台功能一律用开发构建验证Expo Go 不承载后台定位和前台服务性能与电量自查定位精度优化建议精度按业务选档只需要城市级定位如天气、附近门店列表就用Low只走基站和 Wi-Fi几乎不耗电导航、打卡用High多数前台场景Balanced就够了。档位越高 GPS 唤醒越频繁电量消耗不是线性的。后台更新频率放宽到分钟级timeInterval设到 10 秒以上或干脆只设distanceInterval比如移动 100 米才上报。位置数据攒着批量发比每秒上报一次省电得多。善用延迟更新后台任务里配置deferredUpdatesInterval和deferredUpdatesDistance让系统在合适时机补发缓存坐标专门用来压后台功耗。用完即停后台定位任务在流程结束跑完一次、打卡完成后立即stopLocationUpdatesAsync不要留着以防万一。持续运行的定位是电量投诉的第一来源。前台订阅双条件节流同时给watchPositionAsync设timeInterval和distanceInterval用户不动就不刷 UI地图类页面体验更稳。常见故障速查现象原因修复定位 Promise 一直不返回权限被拒或模拟器模拟位置未开启检查getForegroundPermissionsAsync状态按上面清单打开模拟位置iOS 后台权限请求返回 denied 但没弹框用户此前选了Allow Once系统不再提示用Linking打开系统设置让用户手动开启并让应用支持仅前台权限Android 后台任务收不到数据未开启isAndroidBackgroundLocationEnabled或前台服务权限缺失或应用被厂商杀死重新预构建开启前台服务配置真机加电池白名单地理围栏回调从不触发任务没用defineTask在顶层注册或区域数超过平台上限检查任务注册位置iOS 控制在 20 个区域以内定位结果精度值异常大几百米设备处于室内或 Android 只授予了粗略定位申请精确定位室内场景降低精度预期Expo Go 里后台定位完全无效属于平台限制不是代码问题生成开发构建development build再测收尾与进阶资源到这里从一次打卡定位到熄屏跑步轨迹的完整链路都打通了权限配置是地基三组 API 是主体后台任务与电量策略是让它能上线的部分。上线前最后再自查一遍权限文案是否本地化、后台功能是否在开发构建中验证过、任务注册是否都在顶层。想继续深入按这个顺序看官方 API 文档docs/pages/versions/unversioned/sdk/location.mdx任务管理器后台定位与围栏的回调载体docs/pages/versions/unversioned/sdk/task-manager.mdx性能优化指南docs/pages/versions/unversioned/performance.mdx模块源码看原生实现与权限插件packages/expo-location/【免费下载链接】expoAn open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.项目地址: https://gitcode.com/GitHub_Trending/ex/expo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考