Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to stop the foreground serivce in release mode. #489

Open
figureai opened this issue Oct 21, 2024 · 1 comment
Open

Fail to stop the foreground serivce in release mode. #489

figureai opened this issue Oct 21, 2024 · 1 comment

Comments

@figureai
Copy link

I want to start a foreground service in my app and stop it when call the RidingRecordBackgroundService.instaince.stop(). The logic is work very friendly in debug mode. But in the release mode it doesn't work.The foreground service notification isn't removed when call the RidingRecordBackgroundService.instaince.stop(). And there isn't show any error in the Logcat. I don't konw what's wrong in my code. It have confused me two day long. I will appreciate it very much if anyone can help me.


// this will be used as notification channel id
const _notificationChannelId = 'my_foreground';

// this will be used for notification id, So you can update your custom notification with this id.
const _notificationId = 888;
const _channelName = 'RECORD RIDING FOREGROUND SERVICE';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin()
      ..initialize(
        InitializationSettings(
          android: AndroidInitializationSettings('ic_bg_service'),
        ),
      );

@pragma('vm:entry-point')
class RidingRecordBackgroundService {
  static final RidingRecordBackgroundService _instance =
      RidingRecordBackgroundService._internal();
  static RidingRecordBackgroundService get instance => _instance;
  RidingRecordBackgroundService._internal();
  factory RidingRecordBackgroundService() => _instance;
  final FlutterBackgroundService _backbroundService =
      FlutterBackgroundService();

  // Configure the service for iOS and Android with riding record configure
  initConfigure() async {
    // FlutterBackgroundServiceAndroid().invoke('');
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      _notificationChannelId, // id
      _channelName, // title
      description:
          'This channel is used for recording riding foreground service.', // description
      importance: Importance.high, // importance must be at low or higher level
    );

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);
    List<AndroidForegroundType>? foregroundServiceTypes;
    // Android 14 and later need the foreground service types.
    if (Platform.isAndroid) {
      final androidInfo = await DeviceInfoPlugin().androidInfo;
      if (androidInfo.version.sdkInt >= 34) {
        foregroundServiceTypes = [
          AndroidForegroundType.connectedDevice,
        ];
      }
    }

    await _backbroundService.configure(
      iosConfiguration: IosConfiguration(autoStart: false),
      androidConfiguration: AndroidConfiguration(
        autoStart: false,
        autoStartOnBoot: false,
        onStart: _onStart,
        isForegroundMode: true,
        notificationChannelId: _notificationChannelId,
        initialNotificationTitle: '',
        initialNotificationContent: '',
        foregroundServiceNotificationId: _notificationId,
        foregroundServiceTypes: foregroundServiceTypes,
      ),
    );
  }

  static void _onStart(ServiceInstance service) async {
    // Only available for flutter 3.0.0 and later
    DartPluginRegistrant.ensureInitialized();
    // Stop the background service,invoke when FlutterBackgroundService().stopService() is called.
    service.on('stop').listen((event) async {
      await service.stopSelf();
    });
  }

  /// Start the background service for recording riding data.
  start() async {
    final result = await checkNotificaitonPermission();
    Get.log('Notification permission status: $result');
    if (!result) {
      // TODO: Display a dialog to ask user to grant permission
      // openAppSettings();
      return;
    }
    _backbroundService.startService();
  }

  /// Stop the background service for recording riding data.
  stop() async {
    // Availabe for Android 13 and later.
    _backbroundService.invoke("stop");
    // Available for Android 12 and befor.
    flutterLocalNotificationsPlugin.cancel(_notificationId);
    flutterLocalNotificationsPlugin.cancelAll();
    // FlutterBackgroundServiceAndroid().invoke('stopService');
  }
}

@figureai
Copy link
Author

I fixed this bug by adding @pragma('vm:entry-point') above every functions in the RidingRecordBackgroundService class. Maybe the functions is optimized by Dart Vm in release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant