Skip to content

Commit 2b8bca0

Browse files
deakjahnDev-hwang
authored andcommitted
Add stopWithTask override
1 parent e698150 commit 2b8bca0

File tree

7 files changed

+83
-11
lines changed

7 files changed

+83
-11
lines changed

android/src/main/kotlin/com/pravera/flutter_foreground_task/PreferencesKey.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ object PreferencesKey {
5353
const val ALLOW_WAKE_LOCK = "allowWakeLock"
5454
const val ALLOW_WIFI_LOCK = "allowWifiLock"
5555
const val ALLOW_AUTO_RESTART = "allowAutoRestart"
56+
const val STOP_WITH_TASK = "stopWithTask"
5657

57-
// task data
58+
// task data
5859
const val CALLBACK_HANDLE = "callbackHandle"
59-
}
60+
}

android/src/main/kotlin/com/pravera/flutter_foreground_task/models/ForegroundTaskOptions.kt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ data class ForegroundTaskOptions(
1010
val autoRunOnMyPackageReplaced: Boolean,
1111
val allowWakeLock: Boolean,
1212
val allowWifiLock: Boolean,
13-
val allowAutoRestart: Boolean
13+
val allowAutoRestart: Boolean,
14+
val stopWithTask: Boolean?
1415
) {
1516
companion object {
1617
fun getData(context: Context): ForegroundTaskOptions {
@@ -36,6 +37,11 @@ data class ForegroundTaskOptions(
3637
val allowWakeLock = prefs.getBoolean(PrefsKey.ALLOW_WAKE_LOCK, true)
3738
val allowWifiLock = prefs.getBoolean(PrefsKey.ALLOW_WIFI_LOCK, false)
3839
val allowAutoRestart = prefs.getBoolean(PrefsKey.ALLOW_AUTO_RESTART, false)
40+
val stopWithTask: Boolean? =
41+
if (prefs.contains(PrefsKey.STOP_WITH_TASK))
42+
prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)
43+
else
44+
null
3945

4046
return ForegroundTaskOptions(
4147
eventAction = eventAction,
@@ -44,6 +50,7 @@ data class ForegroundTaskOptions(
4450
allowWakeLock = allowWakeLock,
4551
allowWifiLock = allowWifiLock,
4652
allowAutoRestart = allowAutoRestart,
53+
stopWithTask = stopWithTask,
4754
)
4855
}
4956

@@ -62,6 +69,7 @@ data class ForegroundTaskOptions(
6269
val allowWakeLock = map?.get(PrefsKey.ALLOW_WAKE_LOCK) as? Boolean ?: true
6370
val allowWifiLock = map?.get(PrefsKey.ALLOW_WIFI_LOCK) as? Boolean ?: false
6471
val allowAutoRestart = map?.get(PrefsKey.ALLOW_AUTO_RESTART) as? Boolean ?: false
72+
val stopWithTask = map?.get(PrefsKey.STOP_WITH_TASK) as? Boolean
6573

6674
with(prefs.edit()) {
6775
putString(PrefsKey.TASK_EVENT_ACTION, eventActionJsonString)
@@ -70,6 +78,7 @@ data class ForegroundTaskOptions(
7078
putBoolean(PrefsKey.ALLOW_WAKE_LOCK, allowWakeLock)
7179
putBoolean(PrefsKey.ALLOW_WIFI_LOCK, allowWifiLock)
7280
putBoolean(PrefsKey.ALLOW_AUTO_RESTART, allowAutoRestart)
81+
stopWithTask?.let { putBoolean(PrefsKey.STOP_WITH_TASK, it) } ?: remove(PrefsKey.STOP_WITH_TASK)
7382
commit()
7483
}
7584
}
@@ -89,6 +98,7 @@ data class ForegroundTaskOptions(
8998
val allowWakeLock = map?.get(PrefsKey.ALLOW_WAKE_LOCK) as? Boolean
9099
val allowWifiLock = map?.get(PrefsKey.ALLOW_WIFI_LOCK) as? Boolean
91100
val allowAutoRestart = map?.get(PrefsKey.ALLOW_AUTO_RESTART) as? Boolean
101+
val stopWithTask = map?.get(PrefsKey.STOP_WITH_TASK) as? Boolean
92102

93103
with(prefs.edit()) {
94104
eventActionJsonString?.let { putString(PrefsKey.TASK_EVENT_ACTION, it) }
@@ -97,6 +107,7 @@ data class ForegroundTaskOptions(
97107
allowWakeLock?.let { putBoolean(PrefsKey.ALLOW_WAKE_LOCK, it) }
98108
allowWifiLock?.let { putBoolean(PrefsKey.ALLOW_WIFI_LOCK, it) }
99109
allowAutoRestart?.let { putBoolean(PrefsKey.ALLOW_AUTO_RESTART, it) }
110+
stopWithTask?.let { putBoolean(PrefsKey.STOP_WITH_TASK, it) } ?: remove(PrefsKey.STOP_WITH_TASK)
100111
commit()
101112
}
102113
}
@@ -111,4 +122,4 @@ data class ForegroundTaskOptions(
111122
}
112123
}
113124
}
114-
}
125+
}

android/src/main/kotlin/com/pravera/flutter_foreground_task/service/ForegroundService.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import androidx.core.content.ContextCompat
1717
import com.pravera.flutter_foreground_task.FlutterForegroundTaskLifecycleListener
1818
import com.pravera.flutter_foreground_task.RequestCode
1919
import com.pravera.flutter_foreground_task.models.*
20-
import com.pravera.flutter_foreground_task.utils.ForegroundServiceUtils
20+
import com.pravera.flutter_foreground_task.utils.*
21+
import com.pravera.flutter_foreground_task.PreferencesKey as PrefsKey
2122
import kotlinx.coroutines.flow.MutableStateFlow
2223
import kotlinx.coroutines.flow.asStateFlow
2324
import kotlinx.coroutines.flow.update
@@ -125,6 +126,15 @@ class ForegroundService : Service() {
125126
isTimeout = false
126127
loadDataFromPreferences()
127128

129+
val prefs = getSharedPreferences(PrefsKey.FOREGROUND_TASK_OPTIONS_PREFS, Context.MODE_PRIVATE)
130+
if (prefs.contains(PrefsKey.STOP_WITH_TASK) && prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)) {
131+
(application as? Application)?.let {
132+
TrackVisibilityUtils.install(it) {
133+
stopForegroundService()
134+
}
135+
}
136+
}
137+
128138
var action = foregroundServiceStatus.action
129139
val isSetStopWithTaskFlag = ForegroundServiceUtils.isSetStopWithTaskFlag(this)
130140

android/src/main/kotlin/com/pravera/flutter_foreground_task/service/RestartReceiver.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,4 @@ class RestartReceiver : BroadcastReceiver() {
100100
}
101101
}
102102
}
103-
}
103+
}

android/src/main/kotlin/com/pravera/flutter_foreground_task/utils/ForegroundServiceUtils.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,28 @@ import android.content.pm.PackageManager.NameNotFoundException
77
import android.content.pm.ServiceInfo
88
import android.util.Log
99
import com.pravera.flutter_foreground_task.service.ForegroundService
10+
import com.pravera.flutter_foreground_task.PreferencesKey as PrefsKey
1011

1112
class ForegroundServiceUtils {
1213
companion object {
1314
private val TAG = ForegroundServiceUtils::class.java.simpleName
1415

1516
fun isSetStopWithTaskFlag(context: Context): Boolean {
16-
return try {
17+
try {
18+
val prefs = context.getSharedPreferences(PrefsKey.FOREGROUND_TASK_OPTIONS_PREFS, Context.MODE_PRIVATE)
19+
if (prefs.contains(PrefsKey.STOP_WITH_TASK))
20+
return prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)
21+
1722
val pm = context.packageManager
1823
val cName = ComponentName(context, ForegroundService::class.java)
1924
val flags = pm.getServiceInfo(cName, PackageManager.GET_META_DATA).flags
20-
(flags and ServiceInfo.FLAG_STOP_WITH_TASK) != 0
25+
return (flags and ServiceInfo.FLAG_STOP_WITH_TASK) != 0
2126
} catch (e: NameNotFoundException) {
2227
Log.e(TAG, "isSetStopWithTaskFlag >> The service component cannot be found on the system.")
23-
true
28+
return true
2429
} catch (e: Exception) {
2530
Log.e(TAG, "isSetStopWithTaskFlag >> $e")
26-
true
31+
return true
2732
}
2833
}
2934
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.pravera.flutter_foreground_task.utils
2+
3+
import android.app.*
4+
import android.os.*
5+
6+
object TrackVisibilityUtils : Application.ActivityLifecycleCallbacks {
7+
private var installed = false
8+
private val resumed = HashSet<Int>()
9+
private var onAllGone: (() -> Unit)? = null
10+
11+
fun install(application: Application, callback: () -> Unit) {
12+
onAllGone = callback
13+
if (!installed) {
14+
installed = true
15+
application.registerActivityLifecycleCallbacks(this)
16+
}
17+
}
18+
19+
override fun onActivityResumed(activity: Activity) {
20+
resumed.add(System.identityHashCode(activity))
21+
}
22+
23+
override fun onActivityPaused(activity: Activity) {
24+
resumed.remove(System.identityHashCode(activity))
25+
if (resumed.isEmpty()) {
26+
onAllGone?.invoke()
27+
}
28+
}
29+
30+
override fun onActivityStarted(activity: Activity) {}
31+
override fun onActivityStopped(activity: Activity) {}
32+
override fun onActivityCreated(a: Activity, b: Bundle?) {}
33+
override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
34+
override fun onActivityDestroyed(a: Activity) {}
35+
}

lib/models/foreground_task_options.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ForegroundTaskOptions {
1010
this.allowWakeLock = true,
1111
this.allowWifiLock = false,
1212
this.allowAutoRestart = true,
13+
this.stopWithTask,
1314
});
1415

1516
/// The action of onRepeatEvent in [TaskHandler].
@@ -38,6 +39,10 @@ class ForegroundTaskOptions {
3839
/// https://developer.android.com/about/versions/15/behavior-changes-15?hl=pt-br#datasync-timeout
3940
final bool allowAutoRestart;
4041

42+
/// Allows an application to automatically stop when the app task is removed by the system.
43+
/// If set, overrides the service android:stopWithTask behavior.
44+
final bool? stopWithTask;
45+
4146
/// Returns the data fields of [ForegroundTaskOptions] in JSON format.
4247
Map<String, dynamic> toJson() {
4348
return {
@@ -47,9 +52,12 @@ class ForegroundTaskOptions {
4752
'allowWakeLock': allowWakeLock,
4853
'allowWifiLock': allowWifiLock,
4954
'allowAutoRestart': allowAutoRestart,
55+
if (stopWithTask != null) 'stopWithTask': stopWithTask,
5056
};
5157
}
5258

59+
static const _unset = Object();
60+
5361
/// Creates a copy of the object replaced with new values.
5462
ForegroundTaskOptions copyWith({
5563
ForegroundTaskEventAction? eventAction,
@@ -58,6 +66,7 @@ class ForegroundTaskOptions {
5866
bool? allowWakeLock,
5967
bool? allowWifiLock,
6068
bool? allowAutoRestart,
69+
Object? stopWithTask = _unset,
6170
}) =>
6271
ForegroundTaskOptions(
6372
eventAction: eventAction ?? this.eventAction,
@@ -66,5 +75,6 @@ class ForegroundTaskOptions {
6675
allowWakeLock: allowWakeLock ?? this.allowWakeLock,
6776
allowWifiLock: allowWifiLock ?? this.allowWifiLock,
6877
allowAutoRestart: allowAutoRestart ?? this.allowAutoRestart,
78+
stopWithTask: identical(stopWithTask, _unset) ? this.stopWithTask : stopWithTask as bool?,
6979
);
70-
}
80+
}

0 commit comments

Comments
 (0)