Open AhkamKhallaf opened 1 year ago
What do you exactly mean? The api call will be triggered every time the location updates so this is to be expected
On Android/iOS?
On Android/iOS
android such as OPPO A31 ANDROID , SAMSUNG 172 ANDROID
The trackingInterval option actually does not work properly In my emulator which is built with A30, A33 and also on Samsung Galaxy S10(SM G977N) too. if the tracking altitude is not required in your project, geoloactor + flutter_background_service could be a good alternative option it has Stream event and you can adjust it's interval by rxDart throttleTime.
@AhkamKhalaaf Do you do WidgetsFlutterBinding.ensureInitialized();
before the await BackgroundLocationTrackerManager.initialize
?
@AhkamKhalaaf Do you do
WidgetsFlutterBinding.ensureInitialized();
before the awaitBackgroundLocationTrackerManager.initialize
?
yes , i do
Have you tried running the example project? Do you also encounter it then?
Have you tried running the example project? Do you also encounter it then?
yes , it's also, there is the same problem
When exactly do you have this issue?
- With every clean install?
With every clean install
Just for my understanding:
Are these steps correct?
- With every clean install?
With every clean install
i note , now , it does not work with the example project, and not with my project
WidgetsFlutterBinding.ensureInitialized();
/// Background Location initialize
await BackgroundLocationTrackerManager.initialize(
backgroundCallback,
config: const BackgroundLocationTrackerConfig(
androidConfig: AndroidConfig(
distanceFilterMeters: 100,
trackingInterval: Duration(minutes: 5),
enableCancelTrackingAction: false,
),
iOSConfig: IOSConfig(
activityType: ActivityType.FITNESS,
distanceFilterMeters: 100,
restartAfterKill: true,
),
),
);
// this my config
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
final ProviderContainer providerContainer = ProviderContainer();
if (flavorConfig == null) {
await dotenv.load();
}
final Preferences preferences = providerContainer.read(preferencesProvider);
await preferences.init();
await Future.wait(<Future<void>>[
loadImage(splashBackgroundAssets),
loadImage(splashImageAssets),
]);
await EasyLocalization.ensureInitialized();
await providerContainer.read(packageInfoHelperProvider).getPackageVersion();
FlavorConfig.set(
flavorConfig: preferences.flavorConfig ?? flavorConfig ?? FlavorConfig.production(),
read: providerContainer.read,
);
await Firebase.initializeApp();
///Initialize events
EventsHelper().setEvents(
events: <Events>[providerContainer.read(firebaseEventsProvider)],
);
providerContainer.read(apiCoreProvider).init();
/// Disable logs in release mode.
if (kReleaseMode) debugPrint = (String? message, {int? wrapWidth}) {};
/// disable red screen of death in production.
if (!isIntegrationTesting) {
ErrorWidget.builder = (FlutterErrorDetails details) => const SizedBox.shrink();
///Enable & initialize crashlytics when we don't run integration testing.
Crashlytics().enableCrashlytics();
}
await SystemChrome.setPreferredOrientations(
<DeviceOrientation>[DeviceOrientation.portraitUp],
);
await providerContainer.read(appStateProvider).fetchAppToken();
///Initialize dynamic link
DynamicLink().getInitialLink();
final List<Translation> translations = await providerContainer
.read(translationHelperProvider)
.getTranslations(forceRefresh: false, keys: <String>["customTranslations"]);
/// init flutter_bug_logger
Logger.init(FlavorConfig.isStage());
runApp(
showDeviceReview
? DevicePreview(
builder: (BuildContext context) => UncontrolledProviderScope(
container: providerContainer,
child: RestartWidget(
translations: translations,
showDeviceReview: showDeviceReview,
),
),
)
: UncontrolledProviderScope(
container: providerContainer,
child: RestartWidget(
translations: translations,
showDeviceReview: showDeviceReview,
),
),
);
other code which i run inside main
my background meth when location changed , now i just print , it repeat many times
Just for my understanding:
- clean install
- open app
- start tracking
- ISSUE HAPPENS
- quit app
- stop tracking
- open app
- start tracking
- everything works
Are these steps correct?
yes, but the tracking is enabled always
@dev07060 can you confirm you have exactly the same issue in your project?
And is everything working in our example project?
Do you immediately start the tracking or is it after a button press or something (just to make sure you first ask permissions)? For me your config works fine in our example project 🤔
Do you immediately start the tracking or is it after a button press or something (just to make sure you first ask permissions)? For me your config works fine in our example project 🤔
in my project, i depend on silent notification to start track , and i ask user for permissions for location && tracking
Because everything works in the example project, I think in order to help you further we should need a minimal reproducible project. that only contains
Can you provide us with that.
Because everything works in the example project, I think in order to help you further we should need a minimal reproducible project. that only contains
- the bug
- minimal screens
- minimal logic
- no setup
Can you provide us with that.
i use this package to get updated location with fore&&back ground , there's not any ui for that , i depends on silent notification to start &&end tracking , i use Flutter (Channel stable, 3.10.6) , Dart SDK version: 3.0.6 i'll put copy of my main method
Future
if (flavorConfig == null) { await dotenv.load(); }
final Preferences preferences = providerContainer.read(preferencesProvider);
await preferences.init();
await Future.wait(<Future
await EasyLocalization.ensureInitialized();
await providerContainer.read(packageInfoHelperProvider).getPackageVersion();
FlavorConfig.set( flavorConfig: preferences.flavorConfig ?? flavorConfig ?? FlavorConfig.production(), read: providerContainer.read, );
await Firebase.initializeApp();
///Initialize events
EventsHelper().setEvents(
events:
providerContainer.read(apiCoreProvider).init();
/// Disable logs in release mode. if (kReleaseMode) debugPrint = (String? message, {int? wrapWidth}) {};
/// disable red screen of death in production. if (!isIntegrationTesting) { ErrorWidget.builder = (FlutterErrorDetails details) => const SizedBox.shrink();
///Enable & initialize crashlytics when we don't run integration testing.
Crashlytics().enableCrashlytics();
}
await SystemChrome.setPreferredOrientations(
@vanlooverenkoen there is a simple template https://github.com/AhkamKhalaaf/example_location/
Fatal Exception: java.lang.RuntimeException
Unable to create service com.icapps.background_location_tracker.service.LocationUpdatesService: android.app.ForegroundServiceStartNotAllowedException: Service.startForeground() not allowed due to mAllowStartForeground false: service sp.ozeesalon.com/com.icapps.background_location_tracker.service.LocationUpdatesService
Caused by android.app.ForegroundServiceStartNotAllowedException
Service.startForeground() not allowed due to mAllowStartForeground false: service sp.ozeesalon.com/com.icapps.background_location_tracker.service.LocationUpdatesService
android.app.Service.startForeground (Service.java:862)
arrow_right
com.icapps.background_location_tracker.utils.NotificationUtil.startForeground (NotificationUtil.kt:110)
com.icapps.background_location_tracker.service.LocationUpdatesService.startTracking (LocationUpdatesService.kt:176)
com.icapps.background_location_tracker.service.LocationUpdatesService.onCreate (LocationUpdatesService.kt:77)
android.app.ActivityThread.handleCreateService (ActivityThread.java:4651)
The trackingInterval option actually does not work properly In my emulator which is built with A30, A33 and also on Samsung Galaxy S10(SM G977N) too. if the tracking altitude is not required in your project, geoloactor + flutter_background_service could be a good alternative option it has Stream event and you can adjust it's interval by rxDart throttleTime.
oh, it's so important for me , now track interval does not work well for any android device, handleBackgroundUpdated is called for less than one second , when first time run app, but when kill it and run again, it work s fine , any help about this issue @dev07060
Do you immediately start the tracking or is it after a button press or something (just to make sure you first ask permissions)? For me your config works fine in our example project 🤔
yes, i immediately start tracking , inside initState homeScreen , there is a problem with this @ikbendewilliam
Because everything works in the example project, I think in order to help you further we should need a minimal reproducible project. that only contains
- the bug
- minimal screens
- minimal logic
- no setup
Can you provide us with that.
i try example project but not work with my environment , can you tell me your com.google.gms:google-services or any settings can effect @vanlooverenkoen
@AhkamKhalaaf I've checked out your example, thank you for providing this to us. First I have to say that I don't encounter your issue that the backgroundCallback is repeated. It's only called after the set time interval. That being said, there are a few issues I see in your code.
In the handleBackgroundUpdated
you do (data) async => {
This means that you actually return a Set from the method and not execute the content of your method.
More importantly, you don't await the Repo().update(data)
. Meaning that when you do an async call inside this, the background will be disposed as it won't wait for the process to complete. This is the main issue I think in your code.
You start tracking before you have permission, this is not good. You should first ask the user for permission and then start tracking. I would update your init and checkLocation as follows:
void initState() {
super.initState();
checkLocation();
}
...
Future<void> checkLocation() async {
...
_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
_permissionGranted = await location.requestPermission();
if (_permissionGranted != PermissionStatus.granted) {
return;
}
}
await startTRack();
_getTrackingStatus();
_startLocationsUpdatesStream();
debugPrint('${await BackgroundLocationTrackerManager.isTracking()},,isTrackingisTracking');
With these fixes, it works fine for me on my Android device. Can you fix these issues and see if this resolves your issue?
In the
handleBackgroundUpdated
you do(data) async => {
This means that you actually return a Set from the method and not execute the content of your method.More importantly, you don't await the
Repo().update(data)
. Meaning that when you do an async call inside this, the background will be disposed as it won't wait for the process to complete. This is the main issue I think in your code.You start tracking before you have permission, this is not good. You should first ask the user for permission and then start tracking. I would update your init and checkLocation as follows:
void initState() { super.initState(); checkLocation(); } ... Future<void> checkLocation() async { ... _permissionGranted = await location.hasPermission(); if (_permissionGranted == PermissionStatus.denied) { _permissionGranted = await location.requestPermission(); if (_permissionGranted != PermissionStatus.granted) { return; } } await startTRack(); _getTrackingStatus(); _startLocationsUpdatesStream(); debugPrint('${await BackgroundLocationTrackerManager.isTracking()},,isTrackingisTracking');
With these fixes, it works fine for me on my Android device. Can you fix these issues and see if this resolves your issue?
@ikbendewilliam thank you very much for your response,
i follow all your notes and push them to repo , but the issue is still , handleBackgroundUpdated is repeated every second , as you show the location is the same
![Uploading Screenshot_20230914_113907.png…]()
i use in android/build.gradle classpath 'com.android.tools.build:gradle:7.1.2' in android/gradle/wrapper/gradle-wrapper.properties distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip what about you ?@ikbendewilliam
Hi @AhkamKhalaaf the gradle version depends on your local installation and shouldn't matter unless you encounter issues with this. I don't fully know what the issue can be in your case as it is working on our end. Have you tried different devices? And does it work on iOS?
Hi @AhkamKhalaaf the gradle version depends on your local installation and shouldn't matter unless you encounter issues with this. I don't fully know what the issue can be in your case as it is working on our end. Have you tried different devices? And does it work on iOS?
yes , it works with ios platform , yes i try with diffirent emulators and read device
when BackgroundLocationTrackerManager.handleBackgroundUpdated is called , i call api request to save this new location to server , but this request is repeated many times , how cal fix this bug
i use river pod as state management @vanlooverenkoen