transistorsoft / flutter_background_geolocation

Sophisticated, battery-conscious background-geolocation & geofencing with motion-detection
https://www.transistorsoft.com/shop/products/flutter-background-geolocation
Other
651 stars 242 forks source link

While listening with the application closed, the battery level is being sent as a negative value. #1329

Closed ramazancopur closed 2 months ago

ramazancopur commented 4 months ago

Your Environment

Expected Behavior

I want the battery level to be transmitted correctly regardless of the application's state.

Actual Behavior

While listening with the application closed, the battery level is being sent as a negative value.

Debug logs

Logs ``` 2024-07-21 09:52:49.065 ✅-[BackgroundTaskManager createBackgroundTask] 28 2024-07-21 09:52:49.066 ℹ️-[TSDBLogger db_save] Log committed 2024-07-21 09:52:49.068 ✅-[TSHttpService schedulePost] LOCKED: DB714B5D-80DE-4D61-A7A4-650A9AC1E628 2024-07-21 09:52:49.310 ╔═══════════════════════════════════════════════════════════ ║ -[TSLocationManager createMotionTypeChangedHandler]_block_invoke | in_vehicle/0 | isMoving: 1 ╚═══════════════════════════════════════════════════════════ 2024-07-21 09:52:49.310 🔵-[TSLocationManager createMotionTypeChangedHandler]_block_invoke Shake count: 6 2024-07-21 09:52:50.608 🔵-[HttpResponse handleResponse] Response: 200 2024-07-21 09:52:50.617 ✅-[TSHttpService post:]_block_invoke DESTROY: DB714B5D-80DE-4D61-A7A4-650A9AC1E628 2024-07-21 09:52:50.617 ╔═══════════════════════════════════════════════════════════ ║ -[TSHttpService finish:error:] Success: 1 ╚═══════════════════════════════════════════════════════════ 2024-07-21 09:52:50.618 ✅-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 28 OF ( 28 ) 2024-07-21 09:53:00.307 ╔═══════════════════════════════════════════════════════════ ║ -[TSLocationManager createMotionTypeChangedHandler]_block_invoke | in_vehicle/0 | isMoving: 1 ╚═══════════════════════════════════════════════════════════ 2024-07-21 09:53:00.308 🔵-[TSLocationManager createMotionTypeChangedHandler]_block_invoke Shake count: 7 2024-07-21 09:53:11.305 ╔═══════════════════════════════════════════════════════════ ║ -[TSLocationManager createMotionTypeChangedHandler]_block_invoke | in_vehicle/0 | isMoving: 1 ╚═══════════════════════════════════════════════════════════ 2024-07-21 09:53:11.305 🔵-[TSLocationManager createMotionTypeChangedHandler]_block_invoke Shake count: 9 2024-07-21 09:53:13.036 📍<+37.87042656,+32.53541367> +/- 4.75m (speed 10.73 mps / course 169.43) @ 21.07.2024 09:53:13 GMT+03:00 2024-07-21 09:53:13.036 ╔═══════════════════════════════════════════════════════════ ║ -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 1 | df: 200.0m | age: 35 ms ╚═══════════════════════════════════════════════════════════ 2024-07-21 09:53:13.036 🔵-[TSLocationManager locationManager:didUpdateLocations:] Updated distanceFilter, new: 150.000000, old: 200.000000 2024-07-21 09:53:13.036 🔵-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 4.8 2024-07-21 09:53:13.036 ℹ️-[TSConfig persist] 2024-07-21 09:53:13.038 🔵-[TSConfig incrementOdometer:] 1458.3 2024-07-21 09:53:13.047 ✅-[TSLocationManager persistLocation:]_block_invoke INSERT: 5703DA50-FCCB-4606-A1AE-21EBFB46B666 New Log: 2024-08-05 15:29:05.944 ✅-[TSGeofenceManager fireGeofenceEvent:] INSERT: 81FBE7B5-9F03-4D82-B50E-938A99A716AE 2024-08-05 15:29:05.944 ╔═══════════════════════════════════════════════════════════ ║ -[TSHttpService flush:] ╚═══════════════════════════════════════════════════════════ 2024-08-05 15:29:05.944 ✅-[BackgroundTaskManager createBackgroundTask] 251 2024-08-05 15:29:05.944 ✅-[BackgroundTaskManager createBackgroundTask] 252 2024-08-05 15:29:05.944 ╔═══════════════════════════════════════════════════════════ ║ -[TSHttpService flush:] ╚═══════════════════════════════════════════════════════════ 2024-08-05 15:29:05.944 ⚠️-[TSHttpService flush:] Busy with previous request 2024-08-05 15:29:05.944 ℹ️-[TSLocationManager log:message:] onLocation [Location {uuid: EB226B56-161D-4D5B-8792-7B8D44B3BAAA, odometer: 15463.3, sample: true, extras: {}, age: 31941, timestamp: 2024-08-05T12:28:34.000Z, battery: {level: -1.0, is_charging: false}, coords: {speed_accuracy: 4.68, speed: 0.9, longitude: 32.53898619174233, ellipsoidal_altitude: 1044.44, floor: null, heading_accuracy: 180.0, latitude: 37.87557582970895, accuracy: 10.23, altitude_accuracy: 1.69, altitude: 1008.85, heading: 179.88}, is_moving: false, activity: {type: unknown, confidence: 100}}] 2024-08-05 15:29:05.944 ✅-[BackgroundTaskManager createBackgroundTask] 253 2024-08-05 15:29:05.946 ✅-[TSHttpService schedulePost] LOCKED: 81FBE7B5-9F03-4D82-B50E-938A99A716AE 2024-08-05 15:29:05.948 ℹ️+[LocationAuthorization run:onCancel:] status: 3 2024-08-05 15:29:05.948 🎾-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON 2024-08-05 15:29:05.948 ℹ️-[TSLocationManager startMonitoringBackgroundFetch]_block_invoke Configured BackgroundFetch 2024-08-05 15:29:05.949 ✅-[SOMotionDetector startDetection]_block_invoke Enabled M7 MotionActivity updates 2024-08-05 15:29:05.949 ✅-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 253 OF ( 251, 252, 253 ) ```

My db example record: Battery:-1

ramazancopur commented 4 months ago

I have solved the error I experienced, you can close the topic.

ramazancopur commented 3 months ago

I observed that the issue persists in my tests. In addition to the battery error, the Geofence status is not working and the Activity type is always sent as 'unknown'. Additionally, if you need any extra code or information, please let me know and I can provide it.

ramazancopur commented 3 months ago

@christocracy Can you help me ?

christocracy commented 3 months ago

If you’re testing this in the simulator, the simulator doesn’t have a battery or motion api.

ramazancopur commented 3 months ago

I am testing it on a real device. The device model is iPhone 15.

christocracy commented 3 months ago

I suggest you install the /example app from this repo and compare performance.

ramazancopur commented 3 months ago

What should I base the comparison on? I don't know what it will depend on or if I will encounter an error message.

If there is a section you would like to see from my project file, I add

I have been testing and searching for errors for 2-3 days but I could not find a solution.

christocracy commented 3 months ago

What should I base the comparison on?

See if the battery and activity data is satisfactory. The /example app posts location to my demo server.

ramazancopur commented 3 months ago

I have done some tests on the example project before and sent it to your server. The example project works fine. I have a problem when I integrate it into my own project.

I pay special attention to the Ready section. I added it in a single place so that it can be accessed every time the application is opened. The code is attached.

class SplashPage extends StatefulWidget {
  const SplashPage({super.key});

  @override
  State<SplashPage> createState() => _SplashPageState();
}

class _SplashPageState extends State<SplashPage> {
  late AppController appController;
  late SharedPreferences prefs;

  @override
  void initState() {
    super.initState();

    appController = Provider.of<AppController>(context, listen: false);

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
      await readyConfig();
      navigate();
    });
  }

  Future<bool> navigate() async {
    final navigator = Navigator.of(context);

    if (appController.showOnBording()) {
      await appController.changeShowOnbordig(true);
      navigator.pushNamedAndRemoveUntil(
        KRoute.onBordingRoute,
        (_) => false,
      );
    } else {
      navigator.pushNamedAndRemoveUntil(
        KRoute.defaultRoute,
        (_) => false,
      );
    }

    return true;
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: SafeArea(
        child: Center(child: CupertinoActivityIndicator()),
      ),
    );
  }

  Future readyConfig() async {
    prefs = await SharedPreferences.getInstance();
    // Fired whenever a location is recorded
    bg.BackgroundGeolocation.onLocation((bg.Location location) async {
      // ignore: avoid_print
      print('[location] - $location');

      bg.Logger.debug('onLocation $location');
      bg.Logger.debug('onLocation içidir ${location.activity.type} ${location.activity.confidence}');

      bg.BackgroundGeolocation.startBackgroundTask().then((int taskId) async {
        setSoundConfig().then((dynamic value) {
          bg.BackgroundGeolocation.stopBackgroundTask(taskId);
        }).catchError((dynamic error) {
          bg.BackgroundGeolocation.stopBackgroundTask(taskId);
        });
      });
    });

    // Fired whenever the plugin changes motion-state (stationary->moving and vice-versa)
    bg.BackgroundGeolocation.onMotionChange((bg.Location location) async {
      // ignore: avoid_print
      print('[motionchange] - $location');
    });

    // Fired whenever the state of location-services changes.  Always fired at boot
    bg.BackgroundGeolocation.onProviderChange((bg.ProviderChangeEvent event) {
      // ignore: avoid_print
      print('[providerchange] - $event');
    });

    bg.BackgroundGeolocation.onHttp((bg.HttpEvent response) async {
      // ignore: avoid_print
      print('[http] success? ${response.success}, status? ${response.status}');

      bg.Logger.debug(
        "Istek Gönderilme durumu ${response.responseText},${response.status}",
      );
    });

    bg.BackgroundGeolocation.onActivityChange(
        (bg.ActivityChangeEvent event) async {
      print('onActivityChange $event');

      bg.Logger.debug(
          "Activity Change durumu ${event.activity} ${event.confidence}");

      // bg.BackgroundGeolocation.startBackgroundTask().then((int taskId) async {
      //   setGeofence().then((dynamic value) {
      //     bg.BackgroundGeolocation.stopBackgroundTask(taskId);
      //   }).catchError((dynamic error) {
      //     bg.BackgroundGeolocation.stopBackgroundTask(taskId);
      //   });
      // });
    });

    bg.Config config = await _getConfig();

    bg.State state = await bg.BackgroundGeolocation.ready(config);

    bg.Logger.debug(
        "Ready komutu verildi state: $state and config: $config   ${DateTime.now()}");

    print('ready $state');
  }

  Future<bg.Config> _getConfig() async {
    try {
      String phoneNumber =
          prefs.getString('SharedPreferenceEnum.userPhone') ?? '';
      String hashCode = prefs.getString('SharedPreferenceEnum.userToken') ?? '';

      var ringerValue = await Codes.getRingerMode();

      prefs.setInt('SharedPreferenceEnum.ringerMode', ringerValue);

      return bg.Config(
        desiredAccuracy: bg.Config
            .DESIRED_ACCURACY_HIGH, //Doğruluk oranını düzenlemektedir. Ne kadar yüksek doğruluk o kadar yüksek sarj tüketimi demektir.
        distanceFilter:
            50, // Ne kadar uzaklıkta konum kayıtının yapılacağını bildirir.
        stopOnTerminate:
            false, // Uygulama kapatıldığında izlemenin devam edebilmesi için false olarak ayarlandı.
        startOnBoot:
            true, // Cihaz yeniden başlatıldığın da takibin devam edip etmeyeceğini ayarlar true olarak ayarlandı.
        debug: false,
        logLevel: bg.Config.LOG_LEVEL_VERBOSE,
        reset: true,
        url: 'http://-------------------/add-location',
        params: {
          'telefon': phoneNumber,
          'hash': hashCode,
          'sesdurum': ringerValue,
        },
        locationAuthorizationRequest: 'Always',
        backgroundPermissionRationale: bg.PermissionRationale(
          title: "arka_plan_izin_title".tr(),
          message: 'arka_plan_izin_text'.tr(),
          positiveAction: 'arka_plan_izin_change_button'.tr(),
          negativeAction: 'reject'.tr(),
        ),
      );
    } catch (e) {
      return Future.error(e);
    }
  }

  setSoundConfig() async {
    var ringerValue = await Codes.getRingerMode();

    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();

    var ringerCurrentStatus =
        sharedPreferences.getInt(SharedPreferenceEnum.ringerMode.toString());

    if (ringerCurrentStatus != ringerValue) {
      String phoneNumber = sharedPreferences
              .getString(SharedPreferenceEnum.userPhone.toString()) ??
          '';
      String hashCode = sharedPreferences
              .getString(SharedPreferenceEnum.userToken.toString()) ??
          '';

      var state = await bg.BackgroundGeolocation.setConfig(bg.Config(
        params: {
          'telefon': phoneNumber,
          'hash': hashCode,
          'sesdurum': ringerValue,
        },
      ));

      sharedPreferences.setInt(
          SharedPreferenceEnum.ringerMode.toString(), ringerValue);

      print('setconfig $state -- ${state.url}');

      bg.Logger.debug(
          'setSoundConfig -- setConfigden sonra ki statetir $state -- ${state.url}');
    }
    return true;
  }
christocracy commented 3 months ago

See api docs TransistorAuthorizationToken to learn how to configure the plug-in to post data to my demo server so I can view it. Let me know the orgname you choose.

ramazancopur commented 3 months ago

I tested it by walking 2 times. There was no problem, it worked perfectly. I couldn't understand exactly if this problem is related to my server. If it is related to my server, how is the data correct when the phone is in normal mode, but when it is completely turned off, the data is incorrect.

my orgname is "rcosoft-new"

Thank you very much for your interest

christocracy commented 3 months ago

Learn to observe the plug-in logs. See api docs Logger to learn how to add your own log messages.

ramazancopur commented 3 months ago

I am adding a new log. While the application and device screen are closed. I cannot view the logs I added. Also, when I open the screen, the application can send data to my server without any problems.

I can see my own logs starting from 2024-08-07 14:19:34.078. I opened the screen a while ago.

I have been testing for a long time but I still could not solve the problem.

log.txt

update:

In my new walking test, I have arranged my application to send data to the demo server. I did not open the phone screen at all. The same problem occurred on the demo server. I configured the debug mode to be false. You can check it from the demo server. If you want, I can also share the logs of this walking test.

my orgname is rcosoft-new

Thank you again for your interest.

ramazancopur commented 3 months ago

@christocracy Have you examined ? I still haven't figured out what I need to do.

christocracy commented 3 months ago

I looked at your posted data.

Screenshot 2024-08-09 at 12 54 38 PM

From the iOS Docs

If battery monitoring is not enabled, battery state is UIDeviceBatteryStateUnknown and the value of this property is –1.0.

Battery-monitoring is set globally for an app. The plugin automatically initiates Battery monitoring when you call .start() and halts battery-monitoring when you call .stop().

You are probably using some other plugin which is also interacting with the Global Battery-monitoring API.

However, most of your data is valid. It's certainly not unusual to periodically see unknown activity data. The motion API is handled purely by the OS. There's nothing you can do to improve motion API output.

github-actions[bot] commented 2 months ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 2 months ago

This issue was closed because it has been inactive for 14 days since being marked as stale.