Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -119,7 +119,9 @@ object PreferKey {
|
||||
const val ttsTimer = "ttsTimer"
|
||||
const val noAnimScrollPage = "noAnimScrollPage"
|
||||
const val webDavDeviceName = "webDavDeviceName"
|
||||
const val wakeLock = "wakeLock"
|
||||
const val webServiceWakeLock = "webServiceWakeLock"
|
||||
const val audioPlayWakeLock = "audioPlayWakeLock"
|
||||
const val readAloudWakeLock = "readAloudWakeLock"
|
||||
const val showLastUpdateTime = "showLastUpdateTime"
|
||||
|
||||
const val cPrimary = "colorPrimary"
|
||||
|
||||
@@ -423,6 +423,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
appCtx.putPrefInt(PreferKey.sourceEditMaxLine, value)
|
||||
}
|
||||
|
||||
var audioPlayUseWakeLock: Boolean
|
||||
get() = appCtx.getPrefBoolean(PreferKey.audioPlayWakeLock)
|
||||
set(value) {
|
||||
appCtx.putPrefBoolean(PreferKey.audioPlayWakeLock, value)
|
||||
}
|
||||
|
||||
fun detectClickArea() {
|
||||
if (clickActionTL * clickActionTC * clickActionTR
|
||||
* clickActionML * clickActionMC * clickActionMR
|
||||
|
||||
@@ -32,7 +32,7 @@ object BackupConfig {
|
||||
PreferKey.webDavPassword,
|
||||
PreferKey.launcherIcon,
|
||||
PreferKey.bitmapCacheSize,
|
||||
PreferKey.wakeLock
|
||||
PreferKey.webServiceWakeLock
|
||||
)
|
||||
|
||||
//配置忽略标题
|
||||
|
||||
@@ -63,8 +63,12 @@ class AudioPlayService : BaseService(),
|
||||
private set
|
||||
}
|
||||
|
||||
private val useWakeLock = AppConfig.audioPlayUseWakeLock
|
||||
private val wakeLock by lazy {
|
||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "legado:webService")
|
||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "legado:AudioPlayService")
|
||||
.apply {
|
||||
this.setReferenceCounted(false)
|
||||
}
|
||||
}
|
||||
private val mFocusRequest: AudioFocusRequestCompat by lazy {
|
||||
MediaHelp.buildAudioFocusRequestCompat(this)
|
||||
@@ -87,10 +91,8 @@ class AudioPlayService : BaseService(),
|
||||
private var upPlayProgressJob: Job? = null
|
||||
private var playSpeed: Float = 1f
|
||||
|
||||
@SuppressLint("WakelockTimeout")
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
wakeLock.acquire()
|
||||
isRun = true
|
||||
upNotification()
|
||||
exoPlayer.addListener(this)
|
||||
@@ -127,7 +129,7 @@ class AudioPlayService : BaseService(),
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
wakeLock.release()
|
||||
if (useWakeLock) wakeLock.release()
|
||||
isRun = false
|
||||
abandonFocus()
|
||||
exoPlayer.release()
|
||||
@@ -142,6 +144,7 @@ class AudioPlayService : BaseService(),
|
||||
* 播放音频
|
||||
*/
|
||||
private fun play() {
|
||||
if (useWakeLock) wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/)
|
||||
upNotification()
|
||||
if (requestFocus()) {
|
||||
execute(context = Main) {
|
||||
@@ -176,6 +179,7 @@ class AudioPlayService : BaseService(),
|
||||
* 暂停播放
|
||||
*/
|
||||
private fun pause(abandonFocus: Boolean = true) {
|
||||
if (useWakeLock) wakeLock.release()
|
||||
try {
|
||||
pause = true
|
||||
if (abandonFocus) {
|
||||
@@ -197,6 +201,7 @@ class AudioPlayService : BaseService(),
|
||||
* 恢复播放
|
||||
*/
|
||||
private fun resume() {
|
||||
if (useWakeLock) wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/)
|
||||
try {
|
||||
pause = false
|
||||
if (url.isEmpty()) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.content.IntentFilter
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.AudioManager
|
||||
import android.os.Bundle
|
||||
import android.os.PowerManager
|
||||
import android.support.v4.media.session.MediaSessionCompat
|
||||
import android.support.v4.media.session.PlaybackStateCompat
|
||||
import androidx.annotation.CallSuper
|
||||
@@ -27,7 +28,9 @@ import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.book.read.page.entities.TextChapter
|
||||
import io.legado.app.utils.*
|
||||
import kotlinx.coroutines.*
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.audioManager
|
||||
import splitties.systemservices.powerManager
|
||||
|
||||
/**
|
||||
* 朗读服务
|
||||
@@ -51,8 +54,16 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
fun isPlay(): Boolean {
|
||||
return isRun && !pause
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val useWakeLock = appCtx.getPrefBoolean(PreferKey.readAloudWakeLock, false)
|
||||
private val wakeLock by lazy {
|
||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "legado:ReadAloudService")
|
||||
.apply {
|
||||
this.setReferenceCounted(false)
|
||||
}
|
||||
}
|
||||
private val mFocusRequest: AudioFocusRequestCompat by lazy {
|
||||
MediaHelp.buildAudioFocusRequestCompat(this)
|
||||
}
|
||||
@@ -102,6 +113,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (useWakeLock) wakeLock.release()
|
||||
isRun = false
|
||||
pause = true
|
||||
abandonFocus()
|
||||
@@ -150,6 +162,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
}
|
||||
|
||||
open fun play() {
|
||||
if (useWakeLock) wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/)
|
||||
isRun = true
|
||||
pause = false
|
||||
needResumeOnAudioFocusGain = false
|
||||
@@ -161,6 +174,7 @@ abstract class BaseReadAloudService : BaseService(),
|
||||
|
||||
@CallSuper
|
||||
open fun pauseReadAloud(abandonFocus: Boolean = true) {
|
||||
if (useWakeLock) wakeLock.release()
|
||||
pause = true
|
||||
if (abandonFocus) {
|
||||
abandonFocus()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package io.legado.app.service
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
@@ -18,7 +17,6 @@ import io.legado.app.web.HttpServer
|
||||
import io.legado.app.web.WebSocketServer
|
||||
import splitties.init.appCtx
|
||||
import splitties.systemservices.powerManager
|
||||
|
||||
import java.io.IOException
|
||||
|
||||
class WebService : BaseService() {
|
||||
@@ -35,11 +33,19 @@ class WebService : BaseService() {
|
||||
context.stopService<WebService>()
|
||||
}
|
||||
|
||||
fun serve() {
|
||||
appCtx.startService<WebService> {
|
||||
action = "serve"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val useWakeLock = appCtx.getPrefBoolean(PreferKey.wakeLock, false)
|
||||
private val wakeLock by lazy {
|
||||
private val useWakeLock = appCtx.getPrefBoolean(PreferKey.webServiceWakeLock, false)
|
||||
private val wakeLock: PowerManager.WakeLock by lazy {
|
||||
powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "legado:webService")
|
||||
.apply {
|
||||
setReferenceCounted(false)
|
||||
}
|
||||
}
|
||||
private var httpServer: HttpServer? = null
|
||||
private var webSocketServer: WebSocketServer? = null
|
||||
@@ -48,12 +54,9 @@ class WebService : BaseService() {
|
||||
NetworkChangedListener(this)
|
||||
}
|
||||
|
||||
@SuppressLint("WakelockTimeout")
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
if (useWakeLock) {
|
||||
wakeLock.acquire()
|
||||
}
|
||||
if (useWakeLock) wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/)
|
||||
isRun = true
|
||||
notificationContent = getString(R.string.service_starting)
|
||||
upNotification()
|
||||
@@ -78,6 +81,7 @@ class WebService : BaseService() {
|
||||
when (intent?.action) {
|
||||
IntentAction.stop -> stopSelf()
|
||||
"copyHostAddress" -> sendToClip(hostAddress)
|
||||
"serve" -> if (useWakeLock) wakeLock.acquire(10 * 60 * 1000L /*10 minutes*/)
|
||||
else -> upWebServer()
|
||||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
@@ -85,9 +89,7 @@ class WebService : BaseService() {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
if (useWakeLock) {
|
||||
wakeLock.release()
|
||||
}
|
||||
if (useWakeLock) wakeLock.release()
|
||||
networkChangedListener.unRegister()
|
||||
isRun = false
|
||||
if (httpServer?.isAlive == true) {
|
||||
|
||||
@@ -51,7 +51,6 @@ class AudioPlayActivity :
|
||||
|
||||
override val binding by viewBinding(ActivityAudioPlayBinding::inflate)
|
||||
override val viewModel by viewModels<AudioPlayViewModel>()
|
||||
private var menu: Menu? = null
|
||||
private var adjustProgress = false
|
||||
private val timerViewState = mutableStateOf(false)
|
||||
private val progressTimeFormat by lazy {
|
||||
@@ -94,10 +93,10 @@ class AudioPlayActivity :
|
||||
return super.onCompatCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu): Boolean {
|
||||
this.menu = menu
|
||||
upMenu()
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
|
||||
menu.findItem(R.id.menu_login)?.isVisible = !AudioPlay.bookSource?.loginUrl.isNullOrBlank()
|
||||
menu.findItem(R.id.menu_wake_lock)?.isChecked = AppConfig.audioPlayUseWakeLock
|
||||
return super.onMenuOpened(featureId, menu)
|
||||
}
|
||||
|
||||
override fun onCompatOptionsItemSelected(item: MenuItem): Boolean {
|
||||
@@ -111,6 +110,7 @@ class AudioPlayActivity :
|
||||
putExtra("key", it.bookSourceUrl)
|
||||
}
|
||||
}
|
||||
R.id.menu_wake_lock -> AppConfig.audioPlayUseWakeLock = !AppConfig.audioPlayUseWakeLock
|
||||
R.id.menu_copy_audio_url -> sendToClip(AudioPlayService.url)
|
||||
R.id.menu_edit_source -> AudioPlay.bookSource?.let {
|
||||
sourceEditResult.launch {
|
||||
@@ -181,13 +181,6 @@ class AudioPlayActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private fun upMenu() {
|
||||
menu?.let { menu ->
|
||||
menu.findItem(R.id.menu_login)?.isVisible =
|
||||
!AudioPlay.bookSource?.loginUrl.isNullOrBlank()
|
||||
}
|
||||
}
|
||||
|
||||
private fun upCover(path: String?) {
|
||||
BookCover.load(this, path, sourceOrigin = AudioPlay.bookSource?.bookSourceUrl)
|
||||
.into(binding.ivCover)
|
||||
|
||||
@@ -70,7 +70,7 @@ fun String?.isTrue(nullIsTrue: Boolean = false): Boolean {
|
||||
if (this.isNullOrBlank() || this == "null") {
|
||||
return nullIsTrue
|
||||
}
|
||||
return !this.matches("\\s*(?i)(false|no|not|0)\\s*".toRegex())
|
||||
return !this.trim().matches("(?i)^(false|no|not|0)$".toRegex())
|
||||
}
|
||||
|
||||
fun String.splitNotBlank(vararg delimiter: String, limit: Int = 0): Array<String> = run {
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.legado.app.api.controller.BookController
|
||||
import io.legado.app.api.controller.BookSourceController
|
||||
import io.legado.app.api.controller.ReplaceRuleController
|
||||
import io.legado.app.api.controller.RssSourceController
|
||||
import io.legado.app.service.WebService
|
||||
import io.legado.app.utils.FileUtils
|
||||
import io.legado.app.utils.externalFiles
|
||||
import io.legado.app.web.utils.AssetsWeb
|
||||
@@ -18,8 +19,8 @@ import java.io.*
|
||||
class HttpServer(port: Int) : NanoHTTPD(port) {
|
||||
private val assetsWeb = AssetsWeb("web")
|
||||
|
||||
|
||||
override fun serve(session: IHTTPSession): Response {
|
||||
WebService.serve()
|
||||
var returnData: ReturnData? = null
|
||||
val ct = ContentType(session.headers["content-type"]).tryUTF8()
|
||||
session.headers["content-type"] = ct.contentTypeHeader
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package io.legado.app.web
|
||||
|
||||
import fi.iki.elonen.NanoWSD
|
||||
import io.legado.app.service.WebService
|
||||
import io.legado.app.web.socket.BookSourceDebugWebSocket
|
||||
import io.legado.app.web.socket.RssSourceDebugWebSocket
|
||||
|
||||
class WebSocketServer(port: Int) : NanoWSD(port) {
|
||||
|
||||
override fun openWebSocket(handshake: IHTTPSession): WebSocket? {
|
||||
WebService.serve()
|
||||
return when (handshake.uri) {
|
||||
"/bookSourceDebug" -> {
|
||||
BookSourceDebugWebSocket(handshake)
|
||||
|
||||
Reference in New Issue
Block a user