Closed Intellitrack2017 closed 4 months ago
See CHANGELOG and update to latest version.
I've pushed a release-candidate to branch release-4.7.0. This is a major refactor in support of Android 12.
Please try it out:
dependencies
flutter_background_geolocation:
git:
url: https://github.com/transistorsoft/flutter_background_geolocation
ref: release-4.7.0
Context.startForegroundService
with try / catch
: the plugin will now catch exception ForegroundServiceStartNotAllowedException
and automatically retry with an AlarmManager
oneShot event.android.permission.GET_TASKS
traditionally used for detecting when the app has been terminated. The new life-cycle mgmt system can detect Android headless-mode in a much more elegant manner.WhenInUse
behaviour: The plugin will not allow .changePace(true)
to be executed when the app is in the background (since Android forbids location-services to initiated in the background with WhenInUse
).useSignificantChangesOnly
behaviour. Will use a default motionTriggerDelay
with minimum 60000ms, minimum distanceFilter: 250
and enforced stopTimeout: 20
.location.mock
will now be present for iOS when the location is mocked, just like Android.This breaks my app on Android 12. The previous version of the plugin still works on Android 12.
1) The plugin is configured to run as a foreground service. 2) The user starts location services by clicking a button. 3) The user shuts the screen off and leaves the phone stationary for 5 minutes. 4) The location services notification turns off. 5) The user starts moving again, but location services notification does not turn back on. Since this is running as a foreground service, it is still in use and should resume location updates.
bg.Config _getBgConfig() { return bg.Config( reset: true, desiredAccuracy: bg.Config.DESIRED_ACCURACY_HIGH, distanceFilter: 5.0, preventSuspend: true, isMoving: true, stopOnTerminate: true, stopOnStationary: false, startOnBoot: false, stopTimeout: 5, persistMode: bg.Config.PERSIST_MODE_NONE, foregroundService: true, locationAuthorizationRequest: 'WhenInUse', ); }
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" tools:node="remove" />
That’s the correct behaviour. Location-services cannot be initiated in the background with WhenInUse. If you let Config.stopTimeout expire, the plugin enters the stationary state and turns off location-services.
your app must return to the foreground to re-initiate location-services (ie .changePace(true)
)
Using WhenInUse doesn’t come without consequences.
So, the only way to prevent location services from stopping in this scenario is to set stopTimeout to a really large value?
That’s correct.
Can you give us an idea of the battery impact when setting stopTimeout to a really large value?
And you will likely want to use a sane value.
using a value of hundreds of hours would likely not be desirable to your end-user and his/her battery should they forget to launch your app and perform the action which results in .stop()
/ .changePace(false)
.
Can you give us an idea of the battery impact
Try it and see. Let it run in that state over night.
Will do, thanks.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and I will leave this open.
This issue was closed because it has been inactive for 14 days since being marked as stale.
Your Environment
flutter doctor
): [✓] Flutter (Channel stable, 2.5.3, on macOS 11.5.2 20G95 darwin-arm, locale en-IN) • Flutter version 2.5.3 at /Users/teja/Documents/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 18116933e7 (6 months ago), 2021-10-15 10:46:35 -0700 • Engine revision d3ea636dc5 • Dart version 2.14.4 [!] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /Users/user/Library/Android/sdk ✗ cmdline-tools component is missing Run path/to/sdkmanager --install "cmdline-tools;latest" See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run flutter doctor --android-licenses to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.Plugin config:
`void initState() { WidgetsBinding.instance.addObserver(this); _enabled = false;
//// // 1. Listen to events (See docs for all 12 available events). //
// Fired whenever a location is recorded bg.BackgroundGeolocation.onLocation((bg.Location location) { print("Locatiom $location");
});
// Fired whenever the plugin changes motion-state (stationary->moving and vice-versa) bg.BackgroundGeolocation.onMotionChange((bg.Location location) { // print(location); print("Locatiom $location");
});
bg.BackgroundGeolocation.onProviderChange((bg.ProviderChangeEvent event) { print('[Location Test App] - $event'); });
configFlutterBackGroundService();
}
configFlutterBackGroundService() async { SharedPreferences prefs = await SharedPreferences.getInstance();
}
callStartServiceInNAtive() async {
//// // 3. Start the plugin. // bg.BackgroundGeolocation.start().then((bg.State state) { print('[start] success started $state'); _enabled = state.enabled; // To modify config after #ready has been executed, use #setConfig bg.BackgroundGeolocation.setConfig(bg.Config( isMoving: true, )).then((bg.State state) { bg.BackgroundGeolocation.sync(); }); }).catchError((error) { print('[start] starting failed ERROR: $error'); });
}
callStopServiceInNative() async {
if (_enabled) { bg.BackgroundGeolocation.stop() .then((bg.State state) => {
}) .catchError((error) { print('[stop] stoping failed ERROR: $error'); }); } }`
Expected Behavior
We should not get any crashes in the production
Actual Behavior
We are getting 2 crashes in a production app
Crash 1:
Fatal Exception: android.app.ForegroundServiceStartNotAllowedException: startForegroundService() not allowed due to mAllowStartForeground false: service com.affluence.clu/com.transistorsoft.locationmanager.service.LocationRequestService at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:54) at android.app.ForegroundServiceStartNotAllowedException$1.createFromParcel(ForegroundServiceStartNotAllowedException.java:50) at android.os.Parcel.readParcelable(Parcel.java:3379) at android.os.Parcel.createExceptionOrNull(Parcel.java:2466) at android.os.Parcel.createException(Parcel.java:2455) at android.os.Parcel.readException(Parcel.java:2438) at android.os.Parcel.readException(Parcel.java:2380) at android.app.IActivityManager$Stub$Proxy.startService(IActivityManager.java:6103) at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1851) at android.app.ContextImpl.startForegroundService(ContextImpl.java:1827) at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:789) at com.transistorsoft.locationmanager.service.AbstractService$a.run(AbstractService.java:10) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:233) at android.os.Looper.loop(Looper.java:344) at android.app.ActivityThread.main(ActivityThread.java:8204) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)
Crash 2:
Caused by android.database.sqlite.SQLiteCantOpenDatabaseException: unable to open database file (code 14 SQLITE_CANTOPEN): , while compiling: PRAGMA journal_mode at android.database.sqlite.SQLiteConnection.nativePrepareStatement(SQLiteConnection.java) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1045) at android.database.sqlite.SQLiteConnection.executeForString(SQLiteConnection.java:788) at android.database.sqlite.SQLiteConnection.setJournalMode(SQLiteConnection.java:405) at android.database.sqlite.SQLiteConnection.setWalModeFromConfiguration(SQLiteConnection.java:335) at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:258) at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:205) at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:505) at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:206) at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:198) at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:918) at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:898) at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:762) at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:751) at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:373) at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:316) at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:4) at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:4) at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:2) at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java) at androidx.work.impl.model.SystemIdInfoDao_Impl.getWorkSpecIds(SystemIdInfoDao_Impl.java:9) at androidx.work.impl.background.systemjob.SystemJobScheduler.reconcileJobs(SystemJobScheduler.java:20) at androidx.work.impl.utils.ForceStopRunnable.cleanUp(ForceStopRunnable.java:11) at androidx.work.impl.utils.ForceStopRunnable.forceStopRunnable(ForceStopRunnable.java) at androidx.work.impl.utils.ForceStopRunnable.run(ForceStopRunnable.java:31) at androidx.work.impl.utils.SerialExecutor$Task.run(SerialExecutor.java:2) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923)