diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 569f6d190..721545ff0 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,10 @@ * 先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】,提示存储权限,选择允许即可导入成功。 * 注意:由于安卓10更改了权限策略,还需要给「允许安装其他应用」的权限才能导入源。MIUI11也需要此权限。 +**2019/12/16** +* 添加几个主题选择 +* 音频播放添加header支持 + **2019/12/15** * 修复清理缓存会把其他文件删除的问题 * 详情页模糊背景 diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index 9f13a4f39..f76ed3d13 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -75,7 +75,7 @@ interface BookSourceDao { fun update(vararg bookSource: BookSource) @Delete - fun delete(vararg bookSource: BookSource) + fun delete(bookSource: BookSource) @Query("delete from book_sources where bookSourceUrl = :key") fun delete(key: String) 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 3304cbe83..2cedf7542 100644 --- a/app/src/main/java/io/legado/app/service/AudioPlayService.kt +++ b/app/src/main/java/io/legado/app/service/AudioPlayService.kt @@ -9,6 +9,7 @@ import android.graphics.BitmapFactory import android.media.AudioFocusRequest import android.media.AudioManager import android.media.MediaPlayer +import android.net.Uri import android.os.Build import android.os.Handler import android.support.v4.media.session.MediaSessionCompat @@ -44,10 +45,10 @@ class AudioPlayService : BaseService(), companion object { var isRun = false + var pause = false var timeMinute: Int = 0 } - var pause = false private val handler = Handler() private lateinit var audioManager: AudioManager private var mFocusRequest: AudioFocusRequest? = null @@ -91,7 +92,6 @@ class AudioPlayService : BaseService(), Action.prev -> moveToPrev() Action.next -> moveToNext() Action.adjustSpeed -> upSpeed(intent.getFloatExtra("adjust", 1f)) - Action.moveTo -> moveTo(intent.getIntExtra("index", AudioPlay.durChapterIndex)) Action.addTimer -> addTimer() Action.setTimer -> setTimer(intent.getIntExtra("minute", 0)) Action.adjustProgress -> adjustProgress(intent.getIntExtra("position", position)) @@ -121,7 +121,8 @@ class AudioPlayService : BaseService(), AudioPlay.status = Status.PLAY postEvent(Bus.AUDIO_STATE, Status.PLAY) mediaPlayer.reset() - mediaPlayer.setDataSource(url) + val uri = Uri.parse(url) + mediaPlayer.setDataSource(this, uri, AudioPlay.headers()) mediaPlayer.prepareAsync() } catch (e: Exception) { launch { @@ -133,7 +134,7 @@ class AudioPlayService : BaseService(), } private fun pause(pause: Boolean) { - this.pause = pause + AudioPlayService.pause = pause handler.removeCallbacks(mpRunnable) position = mediaPlayer.currentPosition mediaPlayer.pause() @@ -311,16 +312,6 @@ class AudioPlayService : BaseService(), } } - private fun moveTo(index: Int) { - mediaPlayer.pause() - AudioPlay.durChapterIndex = index - AudioPlay.durPageIndex = 0 - AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex - saveRead() - position = 0 - loadContent(AudioPlay.durChapterIndex) - } - private fun moveToPrev() { if (AudioPlay.durChapterIndex > 0) { mediaPlayer.pause() @@ -354,6 +345,7 @@ class AudioPlayService : BaseService(), book.durChapterTime = System.currentTimeMillis() book.durChapterIndex = AudioPlay.durChapterIndex book.durChapterPos = AudioPlay.durPageIndex + book.durChapterTitle = subtitle App.db.bookDao().update(book) } } 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 98e62606d..add1a3fab 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 @@ -21,6 +21,10 @@ object AudioPlay { var webBook: WebBook? = null val loadingChapters = arrayListOf() + fun headers(): Map? { + return webBook?.bookSource?.getHeaderMap() + } + fun play(context: Context) { val intent = Intent(context, AudioPlayService::class.java) intent.action = Action.play @@ -85,12 +89,4 @@ object AudioPlay { } } - fun moveTo(context: Context, index: Int) { - if (AudioPlayService.isRun) { - val intent = Intent(context, AudioPlayService::class.java) - intent.action = Action.moveTo - intent.putExtra("index", index) - 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 47d15704e..2b27a1600 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 @@ -10,6 +10,7 @@ import android.view.MenuItem import android.widget.SeekBar import androidx.lifecycle.Observer import com.bumptech.glide.RequestBuilder +import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -21,6 +22,7 @@ import io.legado.app.help.ImageLoader import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.okButton +import io.legado.app.service.AudioPlayService import io.legado.app.service.help.AudioPlay import io.legado.app.ui.changesource.ChangeSourceDialog import io.legado.app.ui.chapterlist.ChapterListActivity @@ -117,6 +119,7 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a .centerCrop() .into(iv_cover) ImageLoader.load(this, path) + .transition(DrawableTransitionOptions.withCrossFade(1500)) .thumbnail(defaultCover()) .centerCrop() .apply(RequestOptions.bitmapTransform(BlurTransformation(this, 25))) @@ -170,7 +173,16 @@ class AudioPlayActivity : VMBaseActivity(R.layout.activity_a when (requestCode) { requestCodeChapter -> data?.getIntExtra("index", AudioPlay.durChapterIndex)?.let { if (it != AudioPlay.durChapterIndex) { - AudioPlay.moveTo(this, it) + val isPlay = !AudioPlayService.pause + AudioPlay.pause(this) + AudioPlay.status = Status.STOP + AudioPlay.durChapterIndex = it + AudioPlay.durPageIndex = 0 + AudioPlay.book?.durChapterIndex = AudioPlay.durChapterIndex + viewModel.saveRead() + if (isPlay) { + AudioPlay.play(this) + } } } } 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 c236ef787..5adc2c7be 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 @@ -124,13 +124,16 @@ class AudioPlayViewModel(application: Application) : BaseViewModel(application) } } - private fun saveRead() { + fun saveRead() { execute { AudioPlay.book?.let { book -> book.lastCheckCount = 0 book.durChapterTime = System.currentTimeMillis() book.durChapterIndex = AudioPlay.durChapterIndex book.durChapterPos = AudioPlay.durPageIndex + App.db.bookChapterDao().getChapter(book.bookUrl, book.durChapterIndex)?.let { + book.durChapterTitle = it.title + } App.db.bookDao().update(book) } } diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index 00a2ca315..485b3d02b 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt @@ -7,7 +7,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.lifecycle.Observer -import com.bumptech.glide.Glide import com.bumptech.glide.RequestBuilder import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions.bitmapTransform @@ -115,7 +114,7 @@ class BookInfoActivity : .error(R.drawable.image_cover_default) .centerCrop() .into(iv_cover) - Glide.with(this).load(it) + ImageLoader.load(this, it) .transition(DrawableTransitionOptions.withCrossFade(1500)) .thumbnail(defaultCover()) .centerCrop() diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 7b9daf6d2..23bec9842 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -1,5 +1,6 @@ package io.legado.app.ui.book.read +import android.annotation.SuppressLint import android.app.Activity import android.content.Intent import android.net.Uri @@ -8,6 +9,7 @@ import android.text.SpannableStringBuilder import android.view.KeyEvent import android.view.Menu import android.view.MenuItem +import android.view.View import androidx.core.view.isVisible import androidx.lifecycle.Observer import com.jaredrummler.android.colorpicker.ColorPickerDialogListener @@ -18,11 +20,10 @@ import io.legado.app.constant.Status import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.ReadBookConfig -import io.legado.app.lib.dialogs.alert -import io.legado.app.lib.dialogs.noButton -import io.legado.app.lib.dialogs.okButton +import io.legado.app.lib.dialogs.* import io.legado.app.receiver.TimeElectricityReceiver import io.legado.app.service.BaseReadAloudService +import io.legado.app.service.help.Download import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook import io.legado.app.ui.book.read.config.* @@ -38,6 +39,7 @@ import io.legado.app.ui.widget.page.PageView import io.legado.app.ui.widget.page.delegate.PageDelegate import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_read.* +import kotlinx.android.synthetic.main.dialog_download_choice.view.* import kotlinx.android.synthetic.main.view_book_page.* import kotlinx.android.synthetic.main.view_read_menu.* import kotlinx.coroutines.Dispatchers.IO @@ -131,6 +133,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo /** * 菜单 */ + @SuppressLint("InflateParams") override fun onCompatOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.menu_change_source -> { @@ -146,6 +149,26 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo viewModel.refreshContent(it) } } + R.id.menu_download -> ReadBook.book?.let { book -> + alert(titleResource = R.string.download_offline) { + var view: View? = null + customView { + layoutInflater.inflate(R.layout.dialog_download_choice, null).apply { + view = this + edit_start.setText(book.durChapterIndex.toString()) + edit_end.setText(book.totalChapterNum.toString()) + } + } + yesButton { + view?.apply { + val start = edit_start?.text?.toString()?.toInt() ?: 0 + val end = edit_end?.text?.toString()?.toInt() ?: book.totalChapterNum + Download.start(this@ReadBookActivity, book.bookUrl, start, end) + } + } + noButton() + }.show().applyTint() + } } return super.onCompatOptionsItemSelected(item) } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt index 99e32c556..982476466 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt @@ -91,7 +91,8 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) App.db.bookSourceDao().getBookSource(it) }.let { val json = GSON.toJson(it) - val file = FileHelp.getFile(Backup.exportPath + File.separator + "exportBookSource.json") + val file = + FileHelp.getFile(Backup.exportPath + File.separator + "exportBookSource.json") file.writeText(json) } }.onSuccess { diff --git a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt index 18449147e..8a1990b88 100644 --- a/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/chapterlist/ChapterListFragment.kt @@ -48,9 +48,9 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragme viewModel.bookUrl?.let { bookUrl -> App.db.bookChapterDao().observeByBook(bookUrl).observe(viewLifecycleOwner, Observer { adapter.setItems(it) - viewModel.book?.let { - durChapterIndex = it.durChapterIndex - tv_current_chapter_info.text = it.durChapterTitle + viewModel.book?.let { book -> + durChapterIndex = book.durChapterIndex + tv_current_chapter_info.text = book.durChapterTitle recycler_view.scrollToPosition(durChapterIndex) } }) diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt index 0682fd32c..4c042c579 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesActivity.kt @@ -126,6 +126,7 @@ class RssArticlesActivity : VMBaseActivity(R.layout.activi override fun readRss(rssArticle: RssArticle) { viewModel.read(rssArticle) startActivity( + Pair("title", rssArticle.title), Pair("origin", rssArticle.origin), Pair("link", rssArticle.link) ) diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index d84b81e23..f20be3f87 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -25,7 +25,7 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r override fun onActivityCreated(savedInstanceState: Bundle?) { viewModel.callBack = this - title = intent.getStringExtra("title") + title_bar.title = intent.getStringExtra("title") initWebView() initLiveData() viewModel.initData(intent) @@ -59,20 +59,11 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r viewModel.rssArticle?.let { upJavaScriptEnable() val url = NetworkUtils.getAbsoluteURL(it.origin, it.link) + val html = viewModel.clHtml(content) if (viewModel.rssSource?.loadWithBaseUrl == true) { - webView.loadDataWithBaseURL( - url, - "$content", - "text/html", - "utf-8", - url - ) + webView.loadDataWithBaseURL(url, html, "text/html", "utf-8", url) } else { - webView.loadData( - "$content", - "text/html", - "utf-8" - ) + webView.loadData(html, "text/html", "utf-8") } } }) diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt index 52c090072..8c6f56279 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt @@ -77,6 +77,19 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application) { } } + fun clHtml(content: String): String { + return """ + + + + + + + $content + + """ + } + interface CallBack { fun upStarMenu() } diff --git a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt index 80c21103a..25b68e6c3 100644 --- a/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/widget/page/ChapterProvider.kt @@ -4,6 +4,8 @@ import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.ForegroundColorSpan import android.text.style.RelativeSizeSpan +import androidx.core.text.HtmlCompat +import androidx.core.text.HtmlCompat.FROM_HTML_MODE_COMPACT import io.legado.app.App import io.legado.app.data.entities.BookChapter import io.legado.app.lib.theme.accentColor @@ -17,7 +19,9 @@ object ChapterProvider { fun getTextChapter( bookChapter: BookChapter, - content: String, chapterSize: Int + content: String, + chapterSize: Int, + isHtml: Boolean = false ): TextChapter { textView?.let { val textPages = arrayListOf() @@ -26,7 +30,15 @@ object ChapterProvider { var surplusText = content var pageIndex = 0 while (surplusText.isNotEmpty()) { - val spannableStringBuilder = SpannableStringBuilder(surplusText) + val spannableStringBuilder = + if (isHtml) { + HtmlCompat.fromHtml( + surplusText, + FROM_HTML_MODE_COMPACT + ) as SpannableStringBuilder + } else { + SpannableStringBuilder(surplusText) + } if (pageIndex == 0) { val end = surplusText.indexOf("\n") if (end > 0) { diff --git a/app/src/main/java/io/legado/app/web/controller/SourceController.kt b/app/src/main/java/io/legado/app/web/controller/SourceController.kt index 3711092fc..90c774370 100644 --- a/app/src/main/java/io/legado/app/web/controller/SourceController.kt +++ b/app/src/main/java/io/legado/app/web/controller/SourceController.kt @@ -71,7 +71,9 @@ class SourceController { fun deleteSources(postData: String?): ReturnData { kotlin.runCatching { GSON.fromJsonArray(postData)?.let { - App.db.bookSourceDao().delete(*it.toTypedArray()) + it.forEach { source -> + App.db.bookSourceDao().delete(source) + } } } return ReturnData().setData("已执行"/*okSources*/) diff --git a/app/src/main/res/layout/activity_rss_read.xml b/app/src/main/res/layout/activity_rss_read.xml index 5d403f5fe..e2b27076c 100644 --- a/app/src/main/res/layout/activity_rss_read.xml +++ b/app/src/main/res/layout/activity_rss_read.xml @@ -5,6 +5,7 @@ android:orientation="vertical"> diff --git a/app/src/main/res/layout/dialog_download_choice.xml b/app/src/main/res/layout/dialog_download_choice.xml new file mode 100644 index 000000000..9eabee75b --- /dev/null +++ b/app/src/main/res/layout/dialog_download_choice.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + +