Flutter后台定位调用getCurrentPosition报MissingPluginException
Flutter Workmanager后台执行Geolocator定位抛出MissingPluginException异常
问题现象
实现后台获取用户当前位置功能时,后台任务触发后执行到定位逻辑直接抛出未捕获异常,定位功能无法正常运行,异常信息如下:MissingPluginException(No implementation found for method getCurrentPosition on channel flutter.baseflow.com/geolocator)
运行日志
D/FlutterGeolocator( 2882): Disposing Geolocator services E/FlutterGeolocator( 2882): Geolocator position updates stopped D/FlutterGeolocator( 2882): Stopping location service. I/WM-WorkerWrapper( 2882): Worker result SUCCESS for Work [ id=dc416b8a-e86b-4976-b078-9e8698ac1399, tags={ be.tramckrijte.workmanager.BackgroundWorker } ] E/flutter ( 2882): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: MissingPluginException(No implementation found for method getCurrentPosition on channel flutter.baseflow.com/geolocator)
依赖版本
workmanager: ^0.4.0 geolocator: ^8.0.0
现有实现代码
- 后台任务回调函数
//callback function void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { await LocationService.getCurrentLocation(); print("Native called background task-1: $task"); return Future.value(true); }); }
- 初始化逻辑(initState生命周期中调用)
Workmanager().initialize( callbackDispatcher, isInDebugMode: true, ); Workmanager().registerPeriodicTask( "22", fetchBackground, initialDelay: Duration(seconds: 30), frequency: Duration(minutes: 30), );
- 位置获取封装方法
class LocationService { static getCurrentLocation() async { Position position = await Geolocator.getCurrentPosition(desiredAccuracy:LocationAccuracy.best); print(position ); } }
问题根因
Workmanager触发的后台任务运行在独立的Flutter Engine隔离环境中,该隔离环境默认不会自动完成Flutter绑定初始化,也不会自动注册主工程中引用的插件,Geolocator插件未在后台隔离环境完成注册,因此调用定位方法时找不到对应原生实现,抛出MissingPluginException。
解决步骤
- 第一步:修改后台回调函数,在执行任务前完成Flutter绑定初始化
在callbackDispatcher的最顶部,也就是调用Workmanager().executeTask之前添加初始化代码,确保后台隔离环境能正常加载注册插件:void callbackDispatcher() { // 新增:初始化后台隔离环境的Flutter绑定,必须放在最前面 WidgetsFlutterBinding.ensureInitialized(); Workmanager().executeTask((task, inputData) async { await LocationService.getCurrentLocation(); print("Native called background task-1: $task"); return Future.value(true); }); } - 第二步:补全Android端定位权限配置
打开Android工程下的AndroidManifest.xml文件,在manifest节点下添加定位所需权限,缺少后台定位权限也会导致插件后台运行异常:<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />注意:Android 12及以上版本,后台定位权限需要单独向用户申请,不能和前台定位权限同时申请,否则会被系统直接拒绝。
- 第三步:清理构建缓存后重新运行
执行以下命令清理旧的构建缓存,避免插件注册信息未同步更新:flutter clean flutter pub get flutter run - 补充说明:
geolocator 8.0.0版本在部分深度定制的Android系统上,可能因为系统后台进程限制出现定位服务被回收的情况,若上述步骤完成后仍偶发异常,可以升级geolocator到更新的稳定版本。另外Workmanager的周期性任务在不同厂商系统上存在不同的执行频率限制,无法保证15分钟以内的精准触发。
内容的提问来源于stack exchange,提问作者dinesh balan
相关产品推荐
相关产品推荐

