Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ object PreferencesKey {
const val ALLOW_WAKE_LOCK = "allowWakeLock"
const val ALLOW_WIFI_LOCK = "allowWifiLock"
const val ALLOW_AUTO_RESTART = "allowAutoRestart"
const val STOP_WITH_TASK = "stopWithTask"

// task data
// task data
const val CALLBACK_HANDLE = "callbackHandle"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ data class ForegroundTaskOptions(
val autoRunOnMyPackageReplaced: Boolean,
val allowWakeLock: Boolean,
val allowWifiLock: Boolean,
val allowAutoRestart: Boolean
val allowAutoRestart: Boolean,
val stopWithTask: Boolean?
) {
companion object {
fun getData(context: Context): ForegroundTaskOptions {
Expand All @@ -36,6 +37,11 @@ data class ForegroundTaskOptions(
val allowWakeLock = prefs.getBoolean(PrefsKey.ALLOW_WAKE_LOCK, true)
val allowWifiLock = prefs.getBoolean(PrefsKey.ALLOW_WIFI_LOCK, false)
val allowAutoRestart = prefs.getBoolean(PrefsKey.ALLOW_AUTO_RESTART, false)
val stopWithTask: Boolean? =
if (prefs.contains(PrefsKey.STOP_WITH_TASK))
prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)
else
null

return ForegroundTaskOptions(
eventAction = eventAction,
Expand All @@ -44,6 +50,7 @@ data class ForegroundTaskOptions(
allowWakeLock = allowWakeLock,
allowWifiLock = allowWifiLock,
allowAutoRestart = allowAutoRestart,
stopWithTask = stopWithTask,
)
}

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

with(prefs.edit()) {
putString(PrefsKey.TASK_EVENT_ACTION, eventActionJsonString)
Expand All @@ -70,6 +78,7 @@ data class ForegroundTaskOptions(
putBoolean(PrefsKey.ALLOW_WAKE_LOCK, allowWakeLock)
putBoolean(PrefsKey.ALLOW_WIFI_LOCK, allowWifiLock)
putBoolean(PrefsKey.ALLOW_AUTO_RESTART, allowAutoRestart)
stopWithTask?.let { putBoolean(PrefsKey.STOP_WITH_TASK, it) } ?: remove(PrefsKey.STOP_WITH_TASK)
commit()
}
}
Expand All @@ -89,6 +98,7 @@ data class ForegroundTaskOptions(
val allowWakeLock = map?.get(PrefsKey.ALLOW_WAKE_LOCK) as? Boolean
val allowWifiLock = map?.get(PrefsKey.ALLOW_WIFI_LOCK) as? Boolean
val allowAutoRestart = map?.get(PrefsKey.ALLOW_AUTO_RESTART) as? Boolean
val stopWithTask = map?.get(PrefsKey.STOP_WITH_TASK) as? Boolean

with(prefs.edit()) {
eventActionJsonString?.let { putString(PrefsKey.TASK_EVENT_ACTION, it) }
Expand All @@ -97,6 +107,7 @@ data class ForegroundTaskOptions(
allowWakeLock?.let { putBoolean(PrefsKey.ALLOW_WAKE_LOCK, it) }
allowWifiLock?.let { putBoolean(PrefsKey.ALLOW_WIFI_LOCK, it) }
allowAutoRestart?.let { putBoolean(PrefsKey.ALLOW_AUTO_RESTART, it) }
stopWithTask?.let { putBoolean(PrefsKey.STOP_WITH_TASK, it) } ?: remove(PrefsKey.STOP_WITH_TASK)
commit()
}
}
Expand All @@ -111,4 +122,4 @@ data class ForegroundTaskOptions(
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import androidx.core.content.ContextCompat
import com.pravera.flutter_foreground_task.FlutterForegroundTaskLifecycleListener
import com.pravera.flutter_foreground_task.RequestCode
import com.pravera.flutter_foreground_task.models.*
import com.pravera.flutter_foreground_task.utils.ForegroundServiceUtils
import com.pravera.flutter_foreground_task.utils.*
import com.pravera.flutter_foreground_task.PreferencesKey as PrefsKey
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
Expand Down Expand Up @@ -125,6 +126,15 @@ class ForegroundService : Service() {
isTimeout = false
loadDataFromPreferences()

val prefs = getSharedPreferences(PrefsKey.FOREGROUND_TASK_OPTIONS_PREFS, Context.MODE_PRIVATE)
if (prefs.contains(PrefsKey.STOP_WITH_TASK) && prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)) {
(application as? Application)?.let {
TrackVisibilityUtils.install(it) {
stopForegroundService()
}
}
}

var action = foregroundServiceStatus.action
val isSetStopWithTaskFlag = ForegroundServiceUtils.isSetStopWithTaskFlag(this)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@ class RestartReceiver : BroadcastReceiver() {
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ import android.content.pm.PackageManager.NameNotFoundException
import android.content.pm.ServiceInfo
import android.util.Log
import com.pravera.flutter_foreground_task.service.ForegroundService
import com.pravera.flutter_foreground_task.PreferencesKey as PrefsKey

class ForegroundServiceUtils {
companion object {
private val TAG = ForegroundServiceUtils::class.java.simpleName

fun isSetStopWithTaskFlag(context: Context): Boolean {
return try {
try {
val prefs = context.getSharedPreferences(PrefsKey.FOREGROUND_TASK_OPTIONS_PREFS, Context.MODE_PRIVATE)
if (prefs.contains(PrefsKey.STOP_WITH_TASK))
return prefs.getBoolean(PrefsKey.STOP_WITH_TASK, false)

val pm = context.packageManager
val cName = ComponentName(context, ForegroundService::class.java)
val flags = pm.getServiceInfo(cName, PackageManager.GET_META_DATA).flags
(flags and ServiceInfo.FLAG_STOP_WITH_TASK) != 0
return (flags and ServiceInfo.FLAG_STOP_WITH_TASK) != 0
} catch (e: NameNotFoundException) {
Log.e(TAG, "isSetStopWithTaskFlag >> The service component cannot be found on the system.")
true
return true
} catch (e: Exception) {
Log.e(TAG, "isSetStopWithTaskFlag >> $e")
true
return true
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.pravera.flutter_foreground_task.utils

import android.app.*
import android.os.*

object TrackVisibilityUtils : Application.ActivityLifecycleCallbacks {
private var installed = false
private val resumed = HashSet<Int>()
private var onAllGone: (() -> Unit)? = null

fun install(application: Application, callback: () -> Unit) {
onAllGone = callback
if (!installed) {
installed = true
application.registerActivityLifecycleCallbacks(this)
}
}

override fun onActivityResumed(activity: Activity) {
resumed.add(System.identityHashCode(activity))
}

override fun onActivityPaused(activity: Activity) {
resumed.remove(System.identityHashCode(activity))
if (resumed.isEmpty()) {
onAllGone?.invoke()
}
}

override fun onActivityStarted(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivityCreated(a: Activity, b: Bundle?) {}
override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
override fun onActivityDestroyed(a: Activity) {}
}
12 changes: 11 additions & 1 deletion lib/models/foreground_task_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class ForegroundTaskOptions {
this.allowWakeLock = true,
this.allowWifiLock = false,
this.allowAutoRestart = true,
this.stopWithTask,
});

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

/// Allows an application to automatically stop when the app task is removed by the system.
/// If set, overrides the service android:stopWithTask behavior.
final bool? stopWithTask;

/// Returns the data fields of [ForegroundTaskOptions] in JSON format.
Map<String, dynamic> toJson() {
return {
Expand All @@ -47,9 +52,12 @@ class ForegroundTaskOptions {
'allowWakeLock': allowWakeLock,
'allowWifiLock': allowWifiLock,
'allowAutoRestart': allowAutoRestart,
if (stopWithTask != null) 'stopWithTask': stopWithTask,
};
}

static const _unset = Object();

/// Creates a copy of the object replaced with new values.
ForegroundTaskOptions copyWith({
ForegroundTaskEventAction? eventAction,
Expand All @@ -58,6 +66,7 @@ class ForegroundTaskOptions {
bool? allowWakeLock,
bool? allowWifiLock,
bool? allowAutoRestart,
Object? stopWithTask = _unset,
}) =>
ForegroundTaskOptions(
eventAction: eventAction ?? this.eventAction,
Expand All @@ -66,5 +75,6 @@ class ForegroundTaskOptions {
allowWakeLock: allowWakeLock ?? this.allowWakeLock,
allowWifiLock: allowWifiLock ?? this.allowWifiLock,
allowAutoRestart: allowAutoRestart ?? this.allowAutoRestart,
stopWithTask: identical(stopWithTask, _unset) ? this.stopWithTask : stopWithTask as bool?,
);
}
}