Android API34下background_location包触发RECEIVER_EXPORTED安全异常求助
后台定位崩溃:SecurityException 错误
错误日志
D/AndroidRuntime(22315): Shutting down VM E/AndroidRuntime(22315): FATAL EXCEPTION: main E/AndroidRuntime(22315): Process: com.throttle.app.throttlemvp, PID: 22315 E/AndroidRuntime(22315): java.lang.RuntimeException: Unable to create service com.almoullim.background_location.LocationUpdatesService: java.lang.SecurityException: com.throttle.app.throttlemvp: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts E/AndroidRuntime(22315): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4878) E/AndroidRuntime(22315): at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0) E/AndroidRuntime(22315): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2365) E/AndroidRuntime(22315): at android.os.Handler.dispatchMessage(Handler.java:107) E/AndroidRuntime(22315): at android.os.Looper.loopOnce(Looper.java:232) E/AndroidRuntime(22315): at android.os.Looper.loop(Looper.java:317) E/AndroidRuntime(22315): at android.app.ActivityThread.main(ActivityThread.java:8501) E/AndroidRuntime(22315): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime(22315): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) E/AndroidRuntime(22315): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:878) E/AndroidRuntime(22315): Caused by: java.lang.SecurityException: com.throttle.app.throttlemvp: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts E/AndroidRuntime(22315): at android.os.Parcel.createExceptionOrNull(Parcel.java:3182) E/AndroidRuntime(22315): at android.os.Parcel.createException(Parcel.java:3166) E/AndroidRuntime(22315): at android.os.Parcel.readException(Parcel.java:3149) E/AndroidRuntime(22315): at android.os.Parcel.readException(Parcel.java:3091) E/AndroidRuntime(22315): at android.app.IActivityManager$Stub$Proxy.registerReceiverWithFeature(IActivityManager.java:5784) E/AndroidRuntime(22315): at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1853) E/AndroidRuntime(22315): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1793) E/AndroidRuntime(22315): at android.app.ContextImpl.registerReceiver(ContextImpl.java:1781) E/AndroidRuntime(22315): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:756) E/AndroidRuntime(22315): at com.almoullim.background_location.LocationUpdatesService.onCreate(LocationUpdatesService.kt:154) E/AndroidRuntime(22315): at android.app.ActivityThread.handleCreateService(ActivityThread.java:4865) E/AndroidRuntime(22315): ... 9 more E/AndroidRuntime(22315): Caused by: android.os.RemoteException: Remote stack trace: E/AndroidRuntime(22315): at com.android.server.am.ActivityManagerService.registerReceiverWithFeature(ActivityManagerService.java:14337) E/AndroidRuntime(22315): at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2615) E/AndroidRuntime(22315): at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2798) E/AndroidRuntime(22315): at android.os.Binder.execTransactInternal(Binder.java:1496) E/AndroidRuntime(22315): at android.os.Binder.execTransact(Binder.java:1440) E/AndroidRuntime(22315): Lost connection to device.
问题描述
使用background_location包搭配后台服务实现后台定位功能,运行应用时崩溃,抛出上述SecurityException错误。原本期望后台定位能正常运行并周期性推送位置更新。
后台服务代码
import 'dart:async'; import 'package:background_location/background_location.dart'; import 'package:firebase_database/firebase_database.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; //import 'package:location/location.dart' ; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:flutter_background_service_android/flutter_background_service_android.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'globalVariables.dart'; final service = FlutterBackgroundService(); LatLng? _pUserLoc; Future<void> getLocationUpdates() async{ WidgetsFlutterBinding.ensureInitialized(); BackgroundLocation.setAndroidConfiguration(1000); BackgroundLocation.stopLocationService(); BackgroundLocation.startLocationService(); BackgroundLocation.getLocationUpdates((currentLocation) { if(currentLocation.latitude != null && currentLocation.longitude != null){ _pUserLoc = LatLng(currentLocation.latitude!, currentLocation.longitude!); updateDatabaseRide(_pUserLoc!); if (kDebugMode) { print(_pUserLoc); } }}); } Future<void> updateDatabaseRide(LatLng pos) async{ DatabaseReference ref = FirebaseDatabase.instance.ref("bikers/$rideCode/$userName"); await ref.update({ "lat": pos.latitude, "lng": pos.longitude, }); } Future<void> initializeService() async{ await service.configure( iosConfiguration: IosConfiguration( autoStart: true, onForeground: onStart, onBackground: onIosBackground, ), androidConfiguration: AndroidConfiguration( onStart: onStart, isForegroundMode: true, autoStart: true ) ); } @pragma('vm:entry-point') Future<bool> onIosBackground(ServiceInstance service) async{ WidgetsFlutterBinding.ensureInitialized(); //DartPluginRegistrant.ensureInitialized(); return true; } @pragma('vm:entry-point') void onStart(ServiceInstance service) async{ //DartPluginRegistrant.ensureInitialized(); if(service is AndroidServiceInstance){ service.on('setAsForeground').listen((event) {service.setAsForegroundService();}); } service.on('stopService').listen((event) {service.stopSelf();}); Timer.periodic(const Duration(seconds: 1),(timer) async{ if(service is AndroidServiceInstance){ if(await service.isForegroundService()){ service.setForegroundNotificationInfo(title: "Foreground Notification", content: "If you see this, your phone is super sensitive"); } } getLocationUpdates(); if (kDebugMode) { print("background service running"); } service.invoke("update"); }); }
已尝试的解决方案
试过针对Android API 34的RECEIVER_EXPORTED/RECEIVER_NOT_EXPORTED相关解决方案,但未解决问题。
解决办法
1. 升级依赖包版本
background_location旧版本未适配Android 14(API 34)的广播接收器权限要求,直接升级到该包的最新稳定版,通常官方会修复这类系统适配问题。
2. 手动修改安卓原生代码(包未更新时)
如果无法升级包,找到background_location依赖中的LocationUpdatesService.kt文件(错误提示第154行),修改广播接收器注册代码:
// 原注册代码 registerReceiver(receiver, intentFilter) // 修改为(根据需求选其一) registerReceiver(receiver, intentFilter, Context.RECEIVER_NOT_EXPORTED) // 或需要接收外部广播时用 registerReceiver(receiver, intentFilter, Context.RECEIVER_EXPORTED)
3. 修复代码中的重复启停问题
你的定时器每1秒调用一次getLocationUpdates(),每次都会启停定位服务,这会频繁触发系统操作,加剧崩溃风险。修改代码只初始化一次定位服务:
@pragma('vm:entry-point') void onStart(ServiceInstance service) async{ if(service is AndroidServiceInstance){ service.on('setAsForeground').listen((event) {service.setAsForegroundService();}); } service.on('stopService').listen((event) {service.stopSelf();}); // 只初始化一次定位服务 await getLocationUpdates(); Timer.periodic(const Duration(seconds: 1),(timer) async{ if(service is AndroidServiceInstance){ if(await service.isForegroundService()){ service.setForegroundNotificationInfo(title: "Foreground Notification", content: "If you see this, your phone is super sensitive"); } } if (kDebugMode) { print("background service running"); } service.invoke("update"); }); } // 修改getLocationUpdates方法 Future<void> getLocationUpdates() async{ WidgetsFlutterBinding.ensureInitialized(); BackgroundLocation.setAndroidConfiguration(1000); // 仅启动一次服务,无需反复启停 await BackgroundLocation.startLocationService(); BackgroundLocation.getLocationUpdates((currentLocation) { if(currentLocation.latitude != null && currentLocation.longitude != null){ _pUserLoc = LatLng(currentLocation.latitude!, currentLocation.longitude!); updateDatabaseRide(_pUserLoc!); if (kDebugMode) { print(_pUserLoc); } }}); }
4. 切换替代包
如果background_location长期未维护,建议替换为geolocator这类活跃维护的定位包,它会及时适配最新安卓系统要求,稳定性更强。
内容的提问来源于stack exchange,提问作者Garvin Chanderia
相关产品推荐
相关产品推荐

