Horis 2 лет назад
Родитель
Сommit
fe0bec1e98

+ 16 - 1
app/src/main/java/io/legado/app/service/WebService.kt

@@ -7,6 +7,7 @@ import android.net.wifi.WifiManager
 import android.os.Build
 import android.os.PowerManager
 import androidx.core.app.NotificationCompat
+import androidx.core.content.ContextCompat
 import io.legado.app.R
 import io.legado.app.base.BaseService
 import io.legado.app.constant.AppConst
@@ -15,7 +16,16 @@ import io.legado.app.constant.IntentAction
 import io.legado.app.constant.NotificationId
 import io.legado.app.constant.PreferKey
 import io.legado.app.receiver.NetworkChangedListener
-import io.legado.app.utils.*
+import io.legado.app.utils.NetworkUtils
+import io.legado.app.utils.getPrefBoolean
+import io.legado.app.utils.getPrefInt
+import io.legado.app.utils.postEvent
+import io.legado.app.utils.printOnDebug
+import io.legado.app.utils.sendToClip
+import io.legado.app.utils.servicePendingIntent
+import io.legado.app.utils.startService
+import io.legado.app.utils.stopService
+import io.legado.app.utils.toastOnUi
 import io.legado.app.web.HttpServer
 import io.legado.app.web.WebSocketServer
 import splitties.init.appCtx
@@ -33,6 +43,11 @@ class WebService : BaseService() {
             context.startService<WebService>()
         }
 
+        fun startForeground(context: Context) {
+            val intent = Intent(context, WebService::class.java)
+            ContextCompat.startForegroundService(context, intent)
+        }
+
         fun stop(context: Context) {
             context.stopService<WebService>()
         }

+ 12 - 1
app/src/main/java/io/legado/app/service/WebTileService.kt

@@ -1,10 +1,12 @@
 package io.legado.app.service
 
+import android.app.Dialog
 import android.content.Intent
 import android.os.Build
 import android.service.quicksettings.Tile
 import android.service.quicksettings.TileService
 import androidx.annotation.RequiresApi
+import io.legado.app.R
 import io.legado.app.constant.IntentAction
 import io.legado.app.utils.printOnDebug
 
@@ -49,7 +51,16 @@ class WebTileService : TileService() {
         if (WebService.isRun) {
             WebService.stop(this)
         } else {
-            WebService.start(this)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+                val dialog = Dialog(this, R.style.AppTheme_Transparent)
+                dialog.setOnShowListener {
+                    WebService.startForeground(this)
+                    dialog.dismiss()
+                }
+                showDialog(dialog)
+            } else {
+                WebService.start(this)
+            }
         }
     }
 

+ 2 - 2
app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt

@@ -6,7 +6,6 @@ import android.view.View
 import androidx.core.view.isGone
 import androidx.fragment.app.activityViewModels
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.flowWithLifecycle
 import androidx.lifecycle.lifecycleScope
 import androidx.lifecycle.repeatOnLifecycle
 import androidx.recyclerview.widget.GridLayoutManager
@@ -29,6 +28,7 @@ import io.legado.app.ui.book.info.BookInfoActivity
 import io.legado.app.ui.book.read.ReadBookActivity
 import io.legado.app.ui.main.MainViewModel
 import io.legado.app.utils.cnCompare
+import io.legado.app.utils.flowWithLifecycleFirst
 import io.legado.app.utils.observeEvent
 import io.legado.app.utils.setEdgeEffectColor
 import io.legado.app.utils.startActivity
@@ -175,7 +175,7 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books),
 
                     else -> list.sortedByDescending { it.durChapterTime }
                 }
-            }.flowWithLifecycle(viewLifecycleOwner.lifecycle, Lifecycle.State.RESUMED).catch {
+            }.flowWithLifecycleFirst(viewLifecycleOwner.lifecycle, Lifecycle.State.RESUMED).catch {
                 AppLog.put("书架更新出错", it)
             }.conflate().flowOn(Dispatchers.Default).collect { list ->
                 binding.tvEmptyMsg.isGone = list.isNotEmpty()

+ 19 - 0
app/src/main/java/io/legado/app/utils/FlowExtensions.kt

@@ -1,13 +1,17 @@
 package io.legado.app.utils
 
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.repeatOnLifecycle
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.async
 import kotlinx.coroutines.ensureActive
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.FlowCollector
 import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
 import kotlinx.coroutines.flow.channelFlow
 import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flatMapMerge
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
@@ -185,3 +189,18 @@ inline fun <T> Flow<T>.onEachAsyncIndexed(
         }.onEach { semaphore.release() }
     }.buffer(0)
 }
+
+fun <T> Flow<T>.flowWithLifecycleFirst(
+    lifecycle: Lifecycle,
+    minActiveState: Lifecycle.State = Lifecycle.State.STARTED
+): Flow<T> = callbackFlow {
+    if (!lifecycle.currentState.isAtLeast(minActiveState)) {
+        send(first())
+    }
+    lifecycle.repeatOnLifecycle(minActiveState) {
+        this@flowWithLifecycleFirst.collect {
+            send(it)
+        }
+    }
+    close()
+}