Dev-hwang / flutter_foreground_task

This plugin is used to implement a foreground service on the Android platform.
https://pub.dev/packages/flutter_foreground_task
MIT License
140 stars 105 forks source link

Timer.periodic doesn't work on IOS release version #200

Closed Mohamed50 closed 1 month ago

Mohamed50 commented 7 months ago

i'm trying to send me current location to API every 5 minutes while the app is in background. i was able to achieve this by creating a Timer.periodic and call the callback every 5 minutes. everything work fine when i run the app from my Mac into my Iphone. But when i push the app to testFlight and download it from there the timer doesn't work. when you reopen the app again the Timer callback get called immediately.

here is my code where i initialize the service.

    FlutterForegroundTask.init(
      androidNotificationOptions: AndroidNotificationOptions(
        channelId: 'foreground_service',
        channelName: 'Auto Login',
        channelDescription: 'This notification appears when the foreground service is running.',
        channelImportance: NotificationChannelImportance.LOW,
        priority: NotificationPriority.LOW,
        showWhen: true,
        iconData: const NotificationIconData(
          resType: ResourceType.mipmap,
          resPrefix: ResourcePrefix.ic,
          name: 'launcher',
        ),
      ),
      iosNotificationOptions: const IOSNotificationOptions(
        showNotification: true,
        playSound: false,
      ),
      foregroundTaskOptions: const ForegroundTaskOptions(
        interval: 300000,
        // 5 minutes as milliseconds
        isOnceEvent: false,
        autoRunOnBoot: true,
        allowWakeLock: true,
        allowWifiLock: true,
      ),
    );
  }

here is the onStart method where i set the timer

  @override
  void onStart(DateTime timestamp, SendPort? sendPort) async {
    log('Service Started');
    Timer.periodic(const Duration(minutes: 5), (timer) async {
      Location location = await FlLocation.getLocation();
      handleLocationChange(timestamp, sendPort, location, 'Time Listener', true);
    });
  }

here is me callback where i do the api call

  handleLocationChange(DateTime timestamp, SendPort? sendPort, Location location, String type,
      [bool updateNotification = true]) async {
    bool isInRoom = await checkIfInsideRoom(LatLng(location.latitude, location.longitude));
    if (updateNotification) {
      FlutterForegroundTask.updateService(
        notificationTitle: 'User is in office $isInRoom',
        notificationText: '${location.latitude}, ${location.longitude}',
      );
    }
    log('${location.latitude}, ${location.longitude}');

    try {
      final response = await GetConnect().post('https://app-34d7d401-418d-4d77-baa5-9bbe0c7deac1.cleverapps.io/log', {
        "rec_date": DateTime.now().toIso8601String(),
        "details": {
          'user_location': json.encode({
            'latitude': location.latitude.toString(),
            'longitude': location.longitude.toString(),
            'altitude': location.altitude.toString(),
          }),
          'configuration': json.encode({
            'latitude': roomLocation?.latitude.toString(),
            'longitude': roomLocation?.longitude.toString(),
            'radius': roomAreaInMeter.toString(),
          }),
          'isInRoom': isInRoom.toString(),
          "type": type,
          'platform': Platform.operatingSystem,
        },
      });
      log(response.bodyString ?? '');
    } catch (e) {
      log(e.toString());
    }

    // Send data to the main isolate.
    sendPort?.send({
      'latitude': location.latitude,
      'longitude': location.longitude,
      'altitude': location.altitude,
      'isInRoom': isInRoom,
    });
  }

here is a link to the full project repo: https://github.com/Mohamed50/auto_login

Please let me know if i'm doing something wrong i have been stuck with this for a week now. Appreciate any help or suggestion to achieve this and thanks for the great work.

Mohamed50 commented 6 months ago

Still waiting for help here

WingCH commented 1 month ago

This library doesn't seem to implement BGProcessingTaskRequest. But even if you did, it's not possible to send the current location information to the API every 5 minutes This is a limitation of ios You can refer to https://pub.dev/packages/workmanager