mirror of
https://github.com/bitfireAT/davx5-ose
synced 2024-10-15 15:59:18 +00:00
ForegroundService: don't use stopSelf or stopForeground (bitfireAT/davx5#462)
May fix #342
This commit is contained in:
parent
769825b402
commit
ee637e4f6d
|
@ -62,7 +62,9 @@
|
||||||
tools:node="remove">
|
tools:node="remove">
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
<service android:name=".ForegroundService"/>
|
<service
|
||||||
|
android:name=".ForegroundService"
|
||||||
|
android:foregroundServiceType="dataSync" />
|
||||||
|
|
||||||
<!-- Remove the node added by AppAuth (remove only from net.openid.appauth library, not from our flavor manifest files) -->
|
<!-- Remove the node added by AppAuth (remove only from net.openid.appauth library, not from our flavor manifest files) -->
|
||||||
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
|
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
|
||||||
|
|
|
@ -98,7 +98,7 @@ class App: Application(), Thread.UncaughtExceptionHandler, Configuration.Provide
|
||||||
accountsUpdatedListener.listen()
|
accountsUpdatedListener.listen()
|
||||||
|
|
||||||
// foreground service (possible workaround for devices which prevent DAVx5 from being started)
|
// foreground service (possible workaround for devices which prevent DAVx5 from being started)
|
||||||
ForegroundService.startIfActive(this)
|
ForegroundService.startOrStop(this)
|
||||||
|
|
||||||
// watch storage because low storage means synchronization is stopped
|
// watch storage because low storage means synchronization is stopped
|
||||||
storageLowReceiver.listen()
|
storageLowReceiver.listen()
|
||||||
|
|
|
@ -25,25 +25,6 @@ import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
class ForegroundService : Service() {
|
class ForegroundService : Service() {
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
|
|
||||||
/* Call startForeground as soon as possible (must be within 5 seconds after the service has been created).
|
|
||||||
If the foreground service shouldn't remain active (because the setting has been disabled),
|
|
||||||
we'll immediately stop it with stopForeground() in onStartCommand(). */
|
|
||||||
val settingsIntent = Intent(this, AppSettingsActivity::class.java).apply {
|
|
||||||
putExtra(AppSettingsActivity.EXTRA_SCROLL_TO, Settings.FOREGROUND_SERVICE)
|
|
||||||
}
|
|
||||||
val builder = NotificationCompat.Builder(this, NotificationUtils.CHANNEL_STATUS)
|
|
||||||
.setSmallIcon(R.drawable.ic_foreground_notify)
|
|
||||||
.setContentTitle(getString(R.string.foreground_service_notify_title))
|
|
||||||
.setContentText(getString(R.string.foreground_service_notify_text))
|
|
||||||
.setStyle(NotificationCompat.BigTextStyle())
|
|
||||||
.setContentIntent(PendingIntent.getActivity(this, 0, settingsIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
|
|
||||||
.setCategory(NotificationCompat.CATEGORY_STATUS)
|
|
||||||
startForeground(NotificationUtils.NOTIFY_FOREGROUND, builder.build())
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@EntryPoint
|
@EntryPoint
|
||||||
|
@ -52,13 +33,6 @@ class ForegroundService : Service() {
|
||||||
fun settingsManager(): SettingsManager
|
fun settingsManager(): SettingsManager
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts/stops a foreground service, according to the app setting [Settings.FOREGROUND_SERVICE]
|
|
||||||
* if [Settings.BATTERY_OPTIMIZATION] is enabled - meaning DAVx5 is whitelisted from optimization.
|
|
||||||
*/
|
|
||||||
const val ACTION_FOREGROUND = "foreground"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the app is currently exempted from battery optimization.
|
* Whether the app is currently exempted from battery optimization.
|
||||||
* @return true if battery optimization is not applied to the current app; false if battery optimization is applied
|
* @return true if battery optimization is not applied to the current app; false if battery optimization is applied
|
||||||
|
@ -68,28 +42,34 @@ class ForegroundService : Service() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the foreground service is enabled (checked) in the app settings.
|
* Whether the foreground service is enabled (checked) in the app settings.
|
||||||
|
*
|
||||||
* @return true: foreground service enabled; false: foreground service not enabled
|
* @return true: foreground service enabled; false: foreground service not enabled
|
||||||
*/
|
*/
|
||||||
fun foregroundServiceActivated(context: Context): Boolean {
|
private fun shouldBeActive(context: Context): Boolean {
|
||||||
val settingsManager = EntryPointAccessors.fromApplication(context, ForegroundServiceEntryPoint::class.java).settingsManager()
|
val settingsManager = EntryPointAccessors.fromApplication(context, ForegroundServiceEntryPoint::class.java).settingsManager()
|
||||||
return settingsManager.getBooleanOrNull(Settings.FOREGROUND_SERVICE) == true
|
return settingsManager.getBooleanOrNull(Settings.FOREGROUND_SERVICE) == true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the foreground service when enabled in the app settings and applicable.
|
* Starts the foreground service when enabled in the app settings and applicable.
|
||||||
|
* Stops a potentially running foreground service when disabled in the app settings.
|
||||||
*/
|
*/
|
||||||
fun startIfActive(context: Context) {
|
fun startOrStop(context: Context) {
|
||||||
if (foregroundServiceActivated(context)) {
|
val foregroundServiceIntent = Intent(Intent.ACTION_DEFAULT, null, context, ForegroundService::class.java)
|
||||||
|
if (shouldBeActive(context)) {
|
||||||
if (batteryOptimizationWhitelisted(context)) {
|
if (batteryOptimizationWhitelisted(context)) {
|
||||||
val serviceIntent = Intent(ACTION_FOREGROUND, null, context, ForegroundService::class.java)
|
|
||||||
if (Build.VERSION.SDK_INT >= 26)
|
if (Build.VERSION.SDK_INT >= 26)
|
||||||
// we now have 5 seconds to call Service.startForeground() [https://developer.android.com/about/versions/oreo/android-8.0-changes.html#back-all]
|
// After the next call, we have 5 seconds to call startForeground()
|
||||||
context.startForegroundService(serviceIntent)
|
// [https://developer.android.com/about/versions/oreo/android-8.0-changes.html#back-all]
|
||||||
|
context.startForegroundService(foregroundServiceIntent)
|
||||||
else
|
else
|
||||||
context.startService(serviceIntent)
|
context.startService(foregroundServiceIntent)
|
||||||
} else
|
} else
|
||||||
notifyBatteryOptimization(context)
|
notifyBatteryOptimization(context)
|
||||||
}
|
} else
|
||||||
|
try {
|
||||||
|
context.stopService(foregroundServiceIntent)
|
||||||
|
} catch (ignored: Exception) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun notifyBatteryOptimization(context: Context) {
|
private fun notifyBatteryOptimization(context: Context) {
|
||||||
|
@ -111,19 +91,24 @@ class ForegroundService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): Nothing? = null
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
val settingsIntent = Intent(this, AppSettingsActivity::class.java).apply {
|
||||||
// Command is always ACTION_FOREGROUND → re-evaluate foreground setting
|
putExtra(AppSettingsActivity.EXTRA_SCROLL_TO, Settings.FOREGROUND_SERVICE)
|
||||||
if (foregroundServiceActivated(this))
|
|
||||||
// keep service open
|
|
||||||
return START_STICKY
|
|
||||||
else {
|
|
||||||
// don't keep service active
|
|
||||||
stopForeground(true)
|
|
||||||
stopSelf() // Stop the service so that onCreate() will run again for the next command
|
|
||||||
return START_NOT_STICKY
|
|
||||||
}
|
}
|
||||||
|
val builder = NotificationCompat.Builder(this, NotificationUtils.CHANNEL_STATUS)
|
||||||
|
.setSmallIcon(R.drawable.ic_foreground_notify)
|
||||||
|
.setContentTitle(getString(R.string.foreground_service_notify_title))
|
||||||
|
.setContentText(getString(R.string.foreground_service_notify_text))
|
||||||
|
.setStyle(NotificationCompat.BigTextStyle())
|
||||||
|
.setContentIntent(PendingIntent.getActivity(this, 0, settingsIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||||
|
startForeground(NotificationUtils.NOTIFY_FOREGROUND, builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onBind(intent: Intent?): Nothing? = null
|
||||||
|
|
||||||
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) = START_STICKY
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,7 +16,11 @@ import androidx.annotation.UiThread
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.preference.*
|
import androidx.preference.EditTextPreference
|
||||||
|
import androidx.preference.ListPreference
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import androidx.preference.PreferenceFragmentCompat
|
||||||
|
import androidx.preference.SwitchPreferenceCompat
|
||||||
import at.bitfire.cert4android.CustomCertStore
|
import at.bitfire.cert4android.CustomCertStore
|
||||||
import at.bitfire.davdroid.BuildConfig
|
import at.bitfire.davdroid.BuildConfig
|
||||||
import at.bitfire.davdroid.ForegroundService
|
import at.bitfire.davdroid.ForegroundService
|
||||||
|
@ -168,7 +172,7 @@ class AppSettingsActivity: AppCompatActivity() {
|
||||||
isEnabled = settings.getBooleanOrNull(Settings.BATTERY_OPTIMIZATION) == true
|
isEnabled = settings.getBooleanOrNull(Settings.BATTERY_OPTIMIZATION) == true
|
||||||
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
||||||
settings.putBoolean(Settings.FOREGROUND_SERVICE, newValue as Boolean)
|
settings.putBoolean(Settings.FOREGROUND_SERVICE, newValue as Boolean)
|
||||||
requireActivity().startService(Intent(ForegroundService.ACTION_FOREGROUND, null, requireActivity(), ForegroundService::class.java))
|
ForegroundService.startOrStop(requireActivity())
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue