有时,如果应用程序处于终止状态,后台服务会启动,但有时后台服务会因错误而停止:Flutter 引擎已断开连接。连接引擎数 0
主要功能
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeService();
}
如果应用程序处于终止状态,则启动后台服务
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
super.didChangeAppLifecycleState(state);\
if (state == AppLifecycleState.resumed) {
print('_isInForeground');
} else if (state == AppLifecycleState.paused) {
print('_isInBackground');
} else if (state == AppLifecycleState.detached) {
print('_isInKilled');
serviceBackground.startService();
}
}
Flutter后台服务页面
Future<void> initializeService() async {
final serviceBackground = FlutterBackgroundService();
AndroidNotificationChannel channel = const AndroidNotificationChannel(
"App",
"foreground service",
importance: Importance.high,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await serviceBackground.configure(
iosConfiguration: IosConfiguration(),
androidConfiguration: AndroidConfiguration(
onStart: onStart,
isForegroundMode: true,
autoStart: true,
notificationChannelId: "App",
initialNotificationTitle: "foreground service",
initialNotificationContent: "initializing",
foregroundServiceNotificationId: 888,
));
serviceBackground.startService();
}
@pragma('vm-entry-point')
Future<void> onStart(ServiceInstance serviceBackground) async {
WidgetsFlutterBinding.ensureInitialized();
DartPluginRegistrant.ensureInitialized();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
serviceBackground.on('stopService').listen((event) {
print("stopService : $event");
serviceBackground.stopSelf();
});
if (serviceBackground is AndroidServiceInstance) {
if (await serviceBackground.isForegroundService()) {
Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.high,
distanceFilter: 20,
)).listen((Position? position) {
addItem(position?.latitude, position?.longitude);
});
flutterLocalNotificationsPlugin.show(
888,
"Background ON",
"Location Tracked",
const NotificationDetails(
android: AndroidNotificationDetails(
"App",
"foreground service",
ongoing: true,
)),
);
}
}
}
我无法找到问题,因为工作人员有时会启动,但并非总是如此。
据我了解,该问题应该只存在于Android操作系统上;因此,我将在上下文中解释它。
因此,您的方法的问题在于您严重依赖后台服务的插件实现。它有效,但正如你所说 - 并不总是如此。原因是
FlutterBackgroundService
的实现细节及其使用目的 - 位置跟踪。
一般Android前台服务(这就是
FlutterBackgroundService
基本上)可以与位置跟踪一起使用,但它受Android操作系统对所有服务(前台或后台、活动和其他意图诱导元素)的影响 - Android可能决定将其从内存中删除,而您对此无能为力。在 Android Q(10) 及更高版本上,您可以通过启动前台服务来影响此行为,如下所示:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(id, notification, FOREGROUND_SERVICE_TYPE_LOCATION) // This insures your service has higher priority and is less likely to be terminated by Android OS
} else {
startForeground(id, notification)
}
此外,启动
Build.VERSION_CODES.Q
,您需要请求特定权限Manifest.permission.ACCESS_BACKGROUND_LOCATION
,以便能够更好地在后台服务中使用位置跟踪。
开始
Build.VERSION_CODES.P
,您还需要请求Manifest.permission.FOREGROUND_SERVICE
许可。
此外,这些新权限需要明确声明您为何需要跟踪位置数据。它可以是任意样式的对话框,带有或多或少任意的措辞解释,对应用程序的最终用户可见。如果没有它,如果应用程序具有上述
ACCESS_BACKGROUND_LOCATION
权限,则该应用程序将不会被 Play 商店接受。
以上均未在
FlutterBackgroundService
中实现,因此 - 行为中存在故障。您最好的选择是分叉插件,修复它,并为主插件存储库创建 PR,同时使用您自己的修复版本的插件。
希望有帮助。