- [Android] Removed unused
import
related to Flutter V1 embedding.
- [Android] Remove unrequired dependency
appcompat
. - [Android] Bump default
androidx.lifecycle:lifecycle-runtime
version to2.7.0
. - [Android] Add
@NonNull
annotations to flutter plugin methods. - [Android] Enable
multidex
in Android /example.
- Update analysis_options.yaml for pub.dev. There are no code changes from 1.3.4.
- Change return-type of
BackgroundFetch.finish
fromvoid
toFuture<void>
.
- [iOS] Code-sign
TSBackgroundFetch.xcframework
with new Apple Organization (9224-2932 Quebec Inc) certificate.
- [iOS] codesign
TSBackgroundFetch.xcframework
. - [iOS] Add
PrivacyInfo.xcprivacy
into.podfile
config.
- [iOS] Move
PrivacyInfo
->TSBackgroundFetch.xcframework
.
- [iOS] Implement new iOS Privacy Manifest
- [iOS] Remove reference to symbol
BGHealthResearchTask
for now
- [iOS] ensure
scheduleTask
callback is executed on main-thread. - [Android] Update Android Setup Instructions for
flutter >= 3.19.0
(New Android Architecture).
- [iOS] Only allow registration of
BGProcessingTasks
(Permitted background task scheduler identifiers) inInfo.plist
which are prefixed withcom.transistorsoft
. Any other task identifier will be ignored. - [Android] Remove deprecated
registerWith
V1 flutter plugin architecture.
- [Android] Detect and dispose of duplicate events. Android
JobService
has a bug for devices running <= Android M where multiplebackgrou nd-fetch
events could fire within the same second.
- [Android] Android 14 (SDK 34) support..
- [Android] Android 14 support: When using
forceAlarmManager: true
, you must now optionally add the permissionandroid.permission.SCHEDULE_EXACT_ALARM
to yourAndroidManifest
to schedule exact alarms. OtherwiseAlarmManager
will use in-exact alarms. :open_file_folder:AndroidManifest
. NOTE You must include the permission exactly as-shown withandroid:minSdkVersion="34"
.
<manifest>
<!-- [background-fetch] OPTIONAL: allows forceAlarmManager: true to use exact alarms -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:maxSdkVersion="33" />
.
.
.
</manifest>
- [Android] Fix an issue booting the app with
flutter run
with screen off where plugin incorrectly detects the app is headless.
- [Android] Gradle v8 now requires
namespace
attribute in gradle files.
- [Android] Fix NPE in
mEventChannelTask
in certain situations. See #322.
- [Android] [Fix] Add a null-check in didDetachFromEngine, fixing a reported null-pointer exception.
- [Android] [Added] Log the jobId when .scheduleTask is called so that developers can simulate events with
adb shell
.
- [Android] Fix error
FlutterJNI was detached from native C++
when Android back button is pressed. In this case, Flutter detaches theMainActivity
from the app and headless-mode was not being detected.
- [Android] add
@pragma('vm:entry-point')
to lib's_headlessCallbackDispatcher
, required for release builds on Flutter >= 3.3.0.
- [Android] Use
LifecycleManager
for modern headless-detection instead of legacy mechanism requiring permissionGET_TASKS
.
- [iOS] Fix type-error when .start() raises an error (#281)
- [Android] Better error-handling when headlessTask is registered incorrectly (#242)
- [Android] Android 12 compatibility: Add new required permission android.permission.SCHEDULE_EXACT_ALARM
- [Fixed][Android] Fix typo related to requiredNetworkType, causing null pointer error.
- [Changed][Android] Remove deprectated
jcenter
repository. Replaced withmavenCentral
.
- [Changed][Android] Allow multiple calls to .configure to allow re-configuring the fetch task. Existing task will be cancelled and a new periodic fetch task re-scheduled according to new config.
- [Changed][Android] Ignore initial fetch task fired immediately.
- [Changed][Android]
android:exported="false"
onBootReceiver
to resolve reported security analysis.
- Release 1.0.0-nullsafety.3 as 1.0.0
- [Fixed][Android] null check in FetchStreamHandler that mEventSink != null
- [Changed][Android] Add new logic block to isMainActivityActive: compare launchActivityName with task.baseActivity.getClassName()
- [Fixed][Android] Flutter 2 broke Android Headless Task with Null-pointer exception.
- [Fixed][Android] Fix
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.transistorsoft.tsbackgroundfetch.BGTask.getTaskId()' on a null object reference
- [Changed] Implement null-safety (Thanks to @GinoTerlouw).
-
[Added][iOS] Implement two new iOS options for
BackgroundFetch.scheduleTask
:bool requiresNetworkConnectivity
bool requiresCharging
(previously Android-only).
-
[Changed][iOS] Migrate
TSBackgroundFetch.framework
to new.xcframework
for MacCatalyst support with new Apple silcon.
iOS' new .xcframework
requires cocoapods >= 1.10+:
$ pod --version
// if < 1.10.0
$ sudo gem install cocoapods
- [Added] task-timeout callback.
BackgroundFetch.configure
now accepts a 3rd argumentonTimeout
callback. This callback will be executed when the operating system has signalled your task has expired before your task has calledBackgroundFetch.finish(taskId)
. You must stop whatever you're task is doing and executeBackgroundFetch.finish(taskId)
immediately.
BackgroundFetch.configure(BackgroundFetchConfig(
minimumFetchInterval: 15
), (String taskId) { // <-- task callback.
print("[BackgroundFetch] taskId: $taskId");
BackgroundFetch.finish(taskId);
}, (String taskId) { // <-- NEW: task-timeout callback.
// This task has exceeded its allowed running-time. You must stop what you're doing immediately finish(taskId)
print("[BackgroundFetch] TIMEOUT taskId: $taskId");
BackgroundFetch.finish(taskId);
});
- Since the registered Android headless-task (
BackgroundFetch.registerHeadlessTask
) can only receive a single parameter, your headless-task will now receive aHeadlessTask task
instance rather thanString taskId
in order to differentiate task-timeout events.
OLD
void myBackgroundFetchHeadlessTask(String taskId) async { // <-- OLD: String taskId
print("[BackgroundFetch] Headless task: $taskId");
BackgroundFetch.finish(taskId);
}
BackgroundFetch.registerHeadlessTask(myBackgroundFetchHeadlessTask);
NEW
void myBackgroundFetchHeadlessTask(HeadlessTask task) async { // <-- NEW: HeadlessTask now provided.
String taskId = task.taskId; // <-- NEW: Get taskId from HeadlessTask
bool isTimeout = task.timeout; // <-- NEW: true if this task has timed-out.
if (isTimeout) {
// This task has exceeded its allowed running-time. You must stop what you're doing immediately finish(taskId)
print("[BackgroundFetch] Headless TIMEOUT: $taskId");
BackgroundFetch.finish(taskId);
return;
}
print("[BackgroundFetch] Headless task: $taskId");
BackgroundFetch.finish(taskId);
}
BackgroundFetch.registerHeadlessTask(myBackgroundFetchHeadlessTask);
- [Fixed][Android]
com.android.tools.build:gradle:4.0.0
no longer allows "direct local aar dependencies". The Android Setup now requires a custommaven url
to be added to your app's rootandroid/build.gradle
:
allprojects {
repositories {
google()
jcenter()
+ maven {
+ // [required] background_fetch
+ url "${project(':background_fetch').projectDir}/libs"
+ }
}
}
- [Fixed][Android] using
forceAlarmManager: true
fails to restart fetch events after reboot. - [Fixed] Android check
wakeLock.isHeld()
before executingwakeLock.release()
.
- [Fixed] [iOS] bug with
start
plugin after executingstop
.
- [Fixed] [Android] Add
@Keep
annotation toHeadlessTask.java
to prevent minifying this classs in release builds since the SDK uses reflection to find this class.
- [Fixed] [Android]
stopOnTerminate
not cancelling scheduled job / Alarm when fired task fired after terminate.
- [Android] Fix Android NPE in
hasTaskId
for case where plugin is installed first time in had previous version of plugin
- [iOS] It's no longer necessary to
registerBGProcessingTask
inAppDelegate.m
for tasks registered for use with#scheduleTask
. The SDK now reads the App.plist
and automatically registers those tasks found in "Permitted background task scheduler identifiers". Remove all code in yourAppDelegate.m
that referencesTSBackgroundFetch
.
- [Added] [Android] New option
forceAlarmManager
for bypassingJobScheduler
mechanism in favour ofAlarmManager
for more precise scheduling task execution. - [Changed] Migrate iOS deprecated "background-fetch" API to new BGTaskScheduler. See new required steps in iOS Setup.
- [Added] Added new
BackgroundFetch.scheduleTask
method for scheduling custom "onehot" and periodic tasks in addition to the default fetch-task.
BackgroundFetch.configure(BackgroundFetchConfig(
minimumFetchInterval: 15,
stopOnTerminate: false
), (String taskId) { // <-- [NEW] taskId provided to Callback
print("[BackgroundFetch] taskId: $taskId");
switch(taskId) {
case 'foo':
// Handle scheduleTask 'foo'
break;
default:
// Handle default fetch event.
break;
}
BackgroundFetch.finish(taskId); // <-- [NEW] Provided taskId to #finish method.
});
// This event will end up in Callback provided to #configure above.
BackgroundFetch.scheduleTask(TaskConfig(
taskId: 'foo', //<-- required
delay: 60000,
periodic: false
));
- With the introduction of ability to execute custom tasks via
#scheduleTask
, all tasks are executed in the Callback provided to#configure
. As a result, this Callback is now provided an argumentString taskId
. ThistaskId
must now be provided to the#finish
method, so that the SDK knows which task is being#finish
ed.
BackgroundFetch.configure(BackgroundFetchConfig(
minimumFetchInterval: 15,
stopOnTerminate: false
), (String taskId) { // <-- [NEW] taskId provided to Callback
print("[BackgroundFetch] taskId: $taskId");
BackgroundFetch.finish(taskId); // <-- [NEW] Provided taskId to #finish method.
});
And with the Headless Task, as well:
/// This "Headless Task" is run when app is terminated.
void backgroundFetchHeadlessTask(String taskId) async { // <-- 1. Headless task receives String taskId
print("[BackgroundFetch] Headless event received: $taskId");
BackgroundFetch.finish(taskId); // <-- 2. #finish with taskId here as well.
}
void main() {
// Enable integration testing with the Flutter Driver extension.
// See https://flutter.io/testing/ for more info.
runApp(new MyApp());
// Register to receive BackgroundFetch events after app is terminated.
// Requires {stopOnTerminate: false, enableHeadless: true}
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
- [Changed] Upgrade to new Flutter Plugin API "V2". Requires flutter sdk version 1.12. See Upgrading pre 1.12 Android Projects
- [Fixed] Resolve Android StrictMode violations; typically from accessing SharedPreferences on main-thread.
- Fix error
FlutterMain.findBundleAppPath()
. The plugin modified a deprecated API for flutter 1.9.1, breaking those on previous flutter versions. Will use deprecated API for now.
- Implement Android
JobInfo
constraints. - Fix
NSLog
warnings casting tolong
- Default
startOnBoot: true
in example
- Use AndroidX.
- Fixed bug with setting
jobServiceClass
using a reference toHeadlessJobService.class
. This crashes devices < api 21, since Android'sJobService
wasn't available until then. Simply provide the class name as aString
.
- Fixed issue with Android headless config.
- First working implementation
- First working implementation