当应用程序处于终止状态时,Flutter flutter_background_service 并不总是启动

问题描述 投票:0回答:1

有时,如果应用程序处于终止状态,后台服务会启动,但有时后台服务会因错误而停止: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,
        )),
      );
    }
  }
}

我无法找到问题,因为工作人员有时会启动,但并非总是如此。

flutter flutter-workmanager
1个回答
0
投票

据我了解,该问题应该只存在于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,同时使用您自己的修复版本的插件。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.