From 72331a54239c73ffbc111af38afface732bec127 Mon Sep 17 00:00:00 2001 From: kunfei Date: Sat, 9 Nov 2019 11:41:25 +0800 Subject: [PATCH] up --- .../java/io/legado/app/constant/Action.kt | 4 + .../main/java/io/legado/app/constant/Bus.kt | 2 +- .../io/legado/app/help/http/AjaxWebView.kt | 1 + .../io/legado/app/service/AudioPlayService.kt | 123 ++++++++++++++- .../io/legado/app/service/help/AudioPlay.kt | 32 +++- .../legado/app/ui/audio/AudioPlayActivity.kt | 30 +--- .../legado/app/ui/audio/AudioPlayViewModel.kt | 149 +++--------------- .../main/res/layout/activity_audio_play.xml | 6 + 8 files changed, 187 insertions(+), 160 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/Action.kt b/app/src/main/java/io/legado/app/constant/Action.kt index 51ca3ae0f..7af394608 100644 --- a/app/src/main/java/io/legado/app/constant/Action.kt +++ b/app/src/main/java/io/legado/app/constant/Action.kt @@ -12,4 +12,8 @@ object Action { const val nextParagraph = "nextParagraph" const val upTtsSpeechRate = "upTtsSpeechRate" const val adjustProgress = "adjustProgress" + const val prev = "prev" + const val next = "next" + const val moveTo = "moveTo" + const val init = "init" } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/constant/Bus.kt b/app/src/main/java/io/legado/app/constant/Bus.kt index f974bdcca..c02c1bb7d 100644 --- a/app/src/main/java/io/legado/app/constant/Bus.kt +++ b/app/src/main/java/io/legado/app/constant/Bus.kt @@ -14,7 +14,7 @@ object Bus { const val UP_CONFIG = "upConfig" const val OPEN_CHAPTER = "openChapter" const val REPLACE = "replace" - const val AUDIO_NEXT = "audioNext" + const val AUDIO_SUB_TITLE = "audioSubTitle" const val AUDIO_STATE = "audioState" const val AUDIO_PROGRESS = "audioProgress" const val AUDIO_SIZE = "audioSize" diff --git a/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt b/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt index deae70382..6d6c65428 100644 --- a/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt +++ b/app/src/main/java/io/legado/app/help/http/AjaxWebView.kt @@ -197,6 +197,7 @@ class AjaxWebView { return@evaluateJavascript } retry++ + handler.removeCallbacks(this) handler.postDelayed(this, 1000) } } diff --git a/app/src/main/java/io/legado/app/service/AudioPlayService.kt b/app/src/main/java/io/legado/app/service/AudioPlayService.kt index a958a371e..86e4b5939 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -20,11 +20,15 @@ import io.legado.app.constant.Action import io.legado.app.constant.AppConst import io.legado.app.constant.Bus import io.legado.app.constant.Status +import io.legado.app.data.entities.BookChapter +import io.legado.app.help.BookHelp import io.legado.app.help.IntentHelp import io.legado.app.help.MediaHelp import io.legado.app.receiver.MediaButtonReceiver +import io.legado.app.service.help.AudioPlay import io.legado.app.utils.LogUtils import io.legado.app.utils.postEvent +import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.launch import org.jetbrains.anko.toast @@ -72,14 +76,16 @@ class AudioPlayService : BaseService(), intent?.action?.let { action -> when (action) { Action.play -> { - title = intent.getStringExtra("title") ?: "" - subtitle = intent.getStringExtra("subtitle") ?: "" - position = intent.getIntExtra("position", 0) - url = intent.getStringExtra("url") - play() + AudioPlay.book?.let { + title = it.name + position = it.durChapterPos + loadContent(it.durChapterIndex) + } } Action.pause -> pause(true) Action.resume -> resume() + Action.prev -> moveToPrev() + Action.next -> moveToNext() Action.addTimer -> addTimer() Action.setTimer -> setTimer(intent.getIntExtra("minute", 0)) Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position)) @@ -102,6 +108,7 @@ class AudioPlayService : BaseService(), } private fun play() { + postEvent(Bus.AUDIO_SUB_TITLE, subtitle) upNotification() if (requestFocus()) { try { @@ -176,7 +183,7 @@ class AudioPlayService : BaseService(), */ override fun onCompletion(mp: MediaPlayer?) { handler.removeCallbacks(mpRunnable) - postEvent(Bus.AUDIO_NEXT, 1) + moveToNext() } private fun setTimer(minute: Int) { @@ -207,6 +214,110 @@ class AudioPlayService : BaseService(), handler.postDelayed(mpRunnable, 1000) } + + private fun loadContent(index: Int) { + AudioPlay.book?.let { book -> + if (addLoading(index)) { + launch(IO) { + App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter -> + BookHelp.getContent(book, chapter)?.let { + contentLoadFinish(chapter, it) + removeLoading(chapter.index) + } ?: download(chapter) + } ?: removeLoading(index) + } + } + } + } + + private fun download(chapter: BookChapter) { + AudioPlay.book?.let { book -> + AudioPlay.webBook?.getContent(book, chapter, scope = this) + ?.onSuccess(IO) { content -> + if (content.isNullOrEmpty()) { + contentLoadFinish(chapter, getString(R.string.content_empty)) + removeLoading(chapter.index) + } else { + BookHelp.saveContent(book, chapter, content) + contentLoadFinish(chapter, content) + removeLoading(chapter.index) + } + }?.onError { + contentLoadFinish(chapter, it.localizedMessage) + removeLoading(chapter.index) + } + } + } + + private fun addLoading(index: Int): Boolean { + synchronized(this) { + if (AudioPlay.loadingChapters.contains(index)) return false + AudioPlay.loadingChapters.add(index) + return true + } + } + + private fun removeLoading(index: Int) { + synchronized(this) { + AudioPlay.loadingChapters.remove(index) + } + } + + /** + * + */ + private fun contentLoadFinish(chapter: BookChapter, content: String) { + if (chapter.index == AudioPlay.durChapterIndex) { + subtitle = chapter.title + url = content + play() + } + } + + fun moveToPrev() { + if (AudioPlay.durChapterIndex > 0) { + AudioPlay.durChapterIndex-- + AudioPlay.durPageIndex = 0 + AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex + saveRead() + position = 0 + loadContent(AudioPlay.durChapterIndex) + } + } + + fun moveToNext() { + if (AudioPlay.durChapterIndex < AudioPlay.chapterSize - 1) { + AudioPlay.durChapterIndex++ + AudioPlay.durPageIndex = 0 + AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex + saveRead() + position = 0 + loadContent(AudioPlay.durChapterIndex) + } else { + stopSelf() + } + } + + private fun saveRead() { + launch(IO) { + AudioPlay.book?.let { book -> + book.lastCheckCount = 0 + book.durChapterTime = System.currentTimeMillis() + book.durChapterIndex = AudioPlay.durChapterIndex + book.durChapterPos = AudioPlay.durPageIndex + App.db.bookDao().update(book) + } + } + } + + fun saveProgress() { + launch(IO) { + AudioPlay.book?.let { + App.db.bookDao().upProgress(it.bookUrl, AudioPlay.durPageIndex) + } + } + } + /** * 定时 */ diff --git a/app/src/main/java/io/legado/app/service/help/AudioPlay.kt b/app/src/main/java/io/legado/app/service/help/AudioPlay.kt index 2ae666206..b4cc98183 100644 --- a/app/src/main/java/io/legado/app/service/help/AudioPlay.kt +++ b/app/src/main/java/io/legado/app/service/help/AudioPlay.kt @@ -7,7 +7,6 @@ import io.legado.app.constant.Action import io.legado.app.data.entities.Book import io.legado.app.model.WebBook import io.legado.app.service.AudioPlayService -import io.legado.app.ui.audio.AudioPlayViewModel object AudioPlay { var titleData = MutableLiveData() @@ -15,19 +14,14 @@ object AudioPlay { var book: Book? = null var inBookshelf = false var chapterSize = 0 - var callBack: AudioPlayViewModel.CallBack? = null var durChapterIndex = 0 var durPageIndex = 0 var webBook: WebBook? = null val loadingChapters = arrayListOf() - fun play(context: Context, title: String?, subtitle: String, url: String, position: Int) { + fun play(context: Context) { val intent = Intent(context, AudioPlayService::class.java) intent.action = Action.play - intent.putExtra("title", title) - intent.putExtra("subtitle", subtitle) - intent.putExtra("url", url) - intent.putExtra("position", position) context.startService(intent) } @@ -63,4 +57,28 @@ object AudioPlay { context.startService(intent) } } + + fun prev(context: Context) { + if (AudioPlayService.isRun) { + val intent = Intent(context, AudioPlayService::class.java) + intent.action = Action.prev + context.startService(intent) + } + } + + fun next(context: Context) { + if (AudioPlayService.isRun) { + val intent = Intent(context, AudioPlayService::class.java) + intent.action = Action.next + context.startService(intent) + } + } + + fun moveTo(context: Context, index: Int) { + if (AudioPlayService.isRun) { + val intent = Intent(context, AudioPlayService::class.java) + intent.action = Action.moveTo + context.startService(intent) + } + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt index 4214a0016..d700fbfde 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt @@ -13,7 +13,6 @@ import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Bus import io.legado.app.constant.Status -import io.legado.app.data.entities.BookChapter import io.legado.app.help.BlurTransformation import io.legado.app.help.ImageLoader import io.legado.app.help.storage.Backup @@ -35,8 +34,7 @@ import org.jetbrains.anko.sdk27.listeners.onLongClick import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivityForResult -class AudioPlayActivity : VMBaseActivity(R.layout.activity_audio_play), - AudioPlayViewModel.CallBack { +class AudioPlayActivity : VMBaseActivity(R.layout.activity_audio_play) { override val viewModel: AudioPlayViewModel get() = getViewModel(AudioPlayViewModel::class.java) @@ -62,10 +60,10 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a true } iv_skip_next.onClick { - viewModel.moveToNext() + AudioPlay.next(this) } iv_skip_previous.onClick { - viewModel.moveToPrev() + AudioPlay.prev(this) } player_progress.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { @@ -113,21 +111,10 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a when (status) { Status.PLAY -> AudioPlay.pause(this) Status.PAUSE -> AudioPlay.resume(this) - else -> viewModel.loadContent(AudioPlay.durChapterIndex) + else -> AudioPlay.play(this) } } - override fun contentLoadFinish(bookChapter: BookChapter, content: String) { - AudioPlay.play( - this, - AudioPlay.book?.name, - bookChapter.title, - content, - AudioPlay.durPageIndex - ) - viewModel.loadContent(AudioPlay.durChapterIndex + 1) - } - override fun finish() { AudioPlay.book?.let { if (!AudioPlay.inBookshelf) { @@ -160,7 +147,7 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a when (requestCode) { requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let { if (it != AudioPlay.durChapterIndex) { - viewModel.loadContent(it) + AudioPlay.moveTo(this, it) } } } @@ -171,9 +158,6 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a observeEvent(Bus.AUDIO_PLAY_BUTTON) { playButton() } - observeEvent(Bus.AUDIO_NEXT) { - viewModel.moveToNext() - } observeEvent(Bus.AUDIO_STATE) { status = it if (status == Status.PLAY) { @@ -186,12 +170,14 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a AudioPlay.durPageIndex = it if (!adjustProgress) player_progress.progress = it tv_dur_time.text = DateFormatUtils.format(it.toLong(), "mm:ss") - viewModel.saveProgress() } observeEventSticky(Bus.AUDIO_SIZE) { player_progress.max = it tv_all_time.text = DateFormatUtils.format(it.toLong(), "mm:ss") } + observeEventSticky(Bus.AUDIO_SUB_TITLE) { + tv_sub_title.text = it + } } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt index bb4e8884b..0cfa4f042 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt @@ -10,16 +10,6 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp import io.legado.app.model.WebBook import io.legado.app.service.help.AudioPlay -import io.legado.app.service.help.AudioPlay.book -import io.legado.app.service.help.AudioPlay.callBack -import io.legado.app.service.help.AudioPlay.chapterSize -import io.legado.app.service.help.AudioPlay.coverData -import io.legado.app.service.help.AudioPlay.durChapterIndex -import io.legado.app.service.help.AudioPlay.durPageIndex -import io.legado.app.service.help.AudioPlay.inBookshelf -import io.legado.app.service.help.AudioPlay.loadingChapters -import io.legado.app.service.help.AudioPlay.titleData -import io.legado.app.service.help.AudioPlay.webBook import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -27,20 +17,20 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) fun initData(intent: Intent) { execute { - inBookshelf = intent.getBooleanExtra("inBookshelf", true) + AudioPlay.inBookshelf = intent.getBooleanExtra("inBookshelf", true) val bookUrl = intent.getStringExtra("bookUrl") - book = if (!bookUrl.isNullOrEmpty()) { + AudioPlay.book = if (!bookUrl.isNullOrEmpty()) { App.db.bookDao().getBook(bookUrl) } else { App.db.bookDao().lastReadBook } - book?.let { book -> - titleData.postValue(book.name) - coverData.postValue(book.getDisplayCover()) - durChapterIndex = book.durChapterIndex - durPageIndex = book.durChapterPos + AudioPlay.book?.let { book -> + AudioPlay.titleData.postValue(book.name) + AudioPlay.coverData.postValue(book.getDisplayCover()) + AudioPlay.durChapterIndex = book.durChapterIndex + AudioPlay.durPageIndex = book.durChapterPos App.db.bookSourceDao().getBookSource(book.origin)?.let { - webBook = WebBook(it) + AudioPlay.webBook = WebBook(it) } val count = App.db.bookChapterDao().getChapterCount(book.bookUrl) if (count == 0) { @@ -50,10 +40,10 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) loadChapterList(book) } } else { - if (durChapterIndex > count - 1) { - durChapterIndex = count - 1 + if (AudioPlay.durChapterIndex > count - 1) { + AudioPlay.durChapterIndex = count - 1 } - chapterSize = count + AudioPlay.chapterSize = count } } saveRead() @@ -65,7 +55,7 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) changeDruChapterIndex: ((chapters: List) -> Unit)? = null ) { execute { - webBook?.getBookInfo(book, this) + AudioPlay.webBook?.getBookInfo(book, this) ?.onSuccess { loadChapterList(book, changeDruChapterIndex) } @@ -77,12 +67,12 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) changeDruChapterIndex: ((chapters: List) -> Unit)? = null ) { execute { - webBook?.getChapterList(book, this) + AudioPlay.webBook?.getChapterList(book, this) ?.onSuccess(Dispatchers.IO) { cList -> if (!cList.isNullOrEmpty()) { if (changeDruChapterIndex == null) { App.db.bookChapterDao().insert(*cList.toTypedArray()) - chapterSize = cList.size + AudioPlay.chapterSize = cList.size } else { changeDruChapterIndex(cList) } @@ -95,74 +85,18 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) } } - fun loadContent(index: Int) { - book?.let { book -> - if (addLoading(index)) { - execute { - App.db.bookChapterDao().getChapter(book.bookUrl, index)?.let { chapter -> - BookHelp.getContent(book, chapter)?.let { - contentLoadFinish(chapter, it) - removeLoading(chapter.index) - } ?: download(chapter) - } ?: removeLoading(index) - }.onError { - removeLoading(index) - } - } - } - } - - private fun download(chapter: BookChapter) { - book?.let { book -> - webBook?.getContent(book, chapter, scope = this) - ?.onSuccess(Dispatchers.IO) { content -> - if (content.isNullOrEmpty()) { - contentLoadFinish(chapter, context.getString(R.string.content_empty)) - removeLoading(chapter.index) - } else { - BookHelp.saveContent(book, chapter, content) - contentLoadFinish(chapter, content) - removeLoading(chapter.index) - } - }?.onError { - contentLoadFinish(chapter, it.localizedMessage) - removeLoading(chapter.index) - } - } - } - - private fun addLoading(index: Int): Boolean { - synchronized(this) { - if (loadingChapters.contains(index)) return false - loadingChapters.add(index) - return true - } - } - - private fun removeLoading(index: Int) { - synchronized(this) { - loadingChapters.remove(index) - } - } - - private fun contentLoadFinish(chapter: BookChapter, content: String) { - if (chapter.index == durChapterIndex) { - callBack?.contentLoadFinish(chapter, content) - } - } - fun changeTo(book1: Book) { execute { - book?.let { + AudioPlay.book?.let { App.db.bookDao().delete(it.bookUrl) } withContext(Dispatchers.Main) { } App.db.bookDao().insert(book1) - book = book1 + AudioPlay.book = book1 App.db.bookSourceDao().getBookSource(book1.origin)?.let { - webBook = WebBook(it) + AudioPlay.webBook = WebBook(it) } if (book1.tocUrl.isEmpty()) { loadBookInfo(book1) { upChangeDurChapterIndex(book1, it) } @@ -174,64 +108,34 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) private fun upChangeDurChapterIndex(book: Book, chapters: List) { execute { - durChapterIndex = BookHelp.getDurChapterIndexByChapterTitle( + AudioPlay.durChapterIndex = BookHelp.getDurChapterIndexByChapterTitle( book.durChapterTitle, book.durChapterIndex, chapters ) - book.durChapterIndex = durChapterIndex - book.durChapterTitle = chapters[durChapterIndex].title + book.durChapterIndex = AudioPlay.durChapterIndex + book.durChapterTitle = chapters[AudioPlay.durChapterIndex].title App.db.bookDao().update(book) App.db.bookChapterDao().insert(*chapters.toTypedArray()) - chapterSize = chapters.size - } - } - - fun moveToPrev() { - if (durChapterIndex > 0) { - durChapterIndex-- - durPageIndex = 0 - book?.durChapterIndex = durChapterIndex - saveRead() - loadContent(durChapterIndex) - } - } - - fun moveToNext() { - if (durChapterIndex < chapterSize - 1) { - durChapterIndex++ - durPageIndex = 0 - book?.durChapterIndex = durChapterIndex - saveRead() - loadContent(durChapterIndex) - } else { - AudioPlay.stop(context) + AudioPlay.chapterSize = chapters.size } } private fun saveRead() { execute { - book?.let { book -> + AudioPlay.book?.let { book -> book.lastCheckCount = 0 book.durChapterTime = System.currentTimeMillis() - book.durChapterIndex = durChapterIndex - book.durChapterPos = durPageIndex + book.durChapterIndex = AudioPlay.durChapterIndex + book.durChapterPos = AudioPlay.durPageIndex App.db.bookDao().update(book) } } } - fun saveProgress() { - execute { - book?.let { - App.db.bookDao().upProgress(it.bookUrl, durPageIndex) - } - } - } - fun removeFromBookshelf(success: (() -> Unit)?) { execute { - book?.let { + AudioPlay.book?.let { App.db.bookDao().delete(it.bookUrl) } }.onSuccess { @@ -239,7 +143,4 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) } } - interface CallBack { - fun contentLoadFinish(bookChapter: BookChapter, content: String) - } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_audio_play.xml b/app/src/main/res/layout/activity_audio_play.xml index 9ef78bdd8..a61910182 100644 --- a/app/src/main/res/layout/activity_audio_play.xml +++ b/app/src/main/res/layout/activity_audio_play.xml @@ -42,6 +42,12 @@ app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/title_bar" /> + +