pull/34/head
kunfei 5 years ago
parent 24f6c66b15
commit c7c96f93c6
  1. 24
      app/src/main/java/io/legado/app/help/PendingIntentHelp.kt
  2. 87
      app/src/main/java/io/legado/app/help/ReadAloud.kt
  3. 24
      app/src/main/java/io/legado/app/lib/theme/ColorUtils.kt
  4. 4
      app/src/main/java/io/legado/app/lib/theme/prefs/ATEEditTextPreference.kt
  5. 7
      app/src/main/java/io/legado/app/lib/theme/view/ATEStrokeTextView.kt
  6. 9
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  7. 98
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  8. 11
      app/src/main/java/io/legado/app/ui/readbook/ReadBookActivity.kt
  9. 4
      app/src/main/java/io/legado/app/ui/readbook/ReadBookViewModel.kt
  10. 15
      app/src/main/java/io/legado/app/ui/readbook/config/ReadAloudDialog.kt
  11. 3
      app/src/main/java/io/legado/app/ui/widget/image/CircleImageView.kt

@ -1,24 +0,0 @@
package io.legado.app.help
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import io.legado.app.service.TTSReadAloudService
import io.legado.app.ui.readbook.ReadBookActivity
object PendingIntentHelp {
fun readBookActivityPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, ReadBookActivity::class.java)
intent.action = "readBookActivity"
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
fun aloudServicePendingIntent(context: Context, actionStr: String): PendingIntent {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = actionStr
return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}

@ -0,0 +1,87 @@
package io.legado.app.help
import android.content.Context
import android.content.Intent
import io.legado.app.constant.Action
import io.legado.app.service.BaseReadAloudService
import io.legado.app.service.TTSReadAloudService
object ReadAloud {
fun play(
context: Context,
title: String,
subtitle: String,
pageIndex: Int,
dataKey: String,
play: Boolean = true
) {
val readAloudIntent = Intent(context, TTSReadAloudService::class.java)
readAloudIntent.action = Action.play
readAloudIntent.putExtra("title", title)
readAloudIntent.putExtra("subtitle", subtitle)
readAloudIntent.putExtra("pageIndex", pageIndex)
readAloudIntent.putExtra("dataKey", dataKey)
readAloudIntent.putExtra("play", play)
context.startService(readAloudIntent)
}
fun pause(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.pause
context.startService(intent)
}
}
fun resume(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.resume
context.startService(intent)
}
}
fun stop(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.stop
context.startService(intent)
}
}
fun prevParagraph(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.prevParagraph
context.startService(intent)
}
}
fun nextParagraph(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.nextParagraph
context.startService(intent)
}
}
fun upTtsSpeechRate(context: Context) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.upTtsSpeechRate
context.startService(intent)
}
}
fun setTimer(context: Context, minute: Int) {
if (BaseReadAloudService.isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.setTimer
intent.putExtra("minute", minute)
context.startService(intent)
}
}
}

@ -116,9 +116,7 @@ object ColorUtils {
} }
init { init {
if (upper <= lower) { require(upper > lower) { "must be lower < upper" }
throw IllegalArgumentException("must be lower < upper")
}
setAlpha(alpha) setAlpha(alpha)
setLower(lower) setLower(lower)
setUpper(upper) setUpper(upper)
@ -129,10 +127,10 @@ object ColorUtils {
} }
private fun setAlpha(alpha: Int) { private fun setAlpha(alpha: Int) {
var alpha = alpha var alpha1 = alpha
if (alpha > 255) alpha = 255 if (alpha1 > 255) alpha1 = 255
if (alpha < 0) alpha = 0 if (alpha1 < 0) alpha1 = 0
this.alpha = alpha this.alpha = alpha1
} }
private fun getLower(): Int { private fun getLower(): Int {
@ -140,9 +138,9 @@ object ColorUtils {
} }
private fun setLower(lower: Int) { private fun setLower(lower: Int) {
var lower = lower var lower1 = lower
if (lower < 0) lower = 0 if (lower1 < 0) lower1 = 0
this.lower = lower this.lower = lower1
} }
private fun getUpper(): Int { private fun getUpper(): Int {
@ -150,9 +148,9 @@ object ColorUtils {
} }
private fun setUpper(upper: Int) { private fun setUpper(upper: Int) {
var upper = upper var upper1 = upper
if (upper > 255) upper = 255 if (upper1 > 255) upper1 = 255
this.upper = upper this.upper = upper1
} }
} }
} }

@ -92,9 +92,7 @@ class ATEEditTextPreference(context: Context?, attrs: AttributeSet?) : EditTextP
protected fun onBindDialogView(view: View) { protected fun onBindDialogView(view: View) {
editText = view.findViewById(android.R.id.edit) editText = view.findViewById(android.R.id.edit)
if (editText == null) { checkNotNull(editText) { "Dialog view must contain an EditText with id" + " @android:id/edit" }
throw IllegalStateException("Dialog view must contain an EditText with id" + " @android:id/edit")
}
view.findViewById<TextView>(android.R.id.message).visibility = View.GONE view.findViewById<TextView>(android.R.id.message).visibility = View.GONE

@ -7,6 +7,7 @@ import io.legado.app.R
import io.legado.app.lib.theme.Selector import io.legado.app.lib.theme.Selector
import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.ThemeStore
import io.legado.app.utils.dp import io.legado.app.utils.dp
import io.legado.app.utils.getCompatColor
class ATEStrokeTextView(context: Context, attrs: AttributeSet) : AppCompatTextView(context, attrs) { class ATEStrokeTextView(context: Context, attrs: AttributeSet) : AppCompatTextView(context, attrs) {
@ -14,16 +15,16 @@ class ATEStrokeTextView(context: Context, attrs: AttributeSet) : AppCompatTextVi
background = Selector.shapeBuild() background = Selector.shapeBuild()
.setCornerRadius(1.dp) .setCornerRadius(1.dp)
.setStrokeWidth(1.dp) .setStrokeWidth(1.dp)
.setDisabledStrokeColor(context.resources.getColor(R.color.md_grey_500)) .setDisabledStrokeColor(context.getCompatColor(R.color.md_grey_500))
.setDefaultStrokeColor(ThemeStore.textColorSecondary(context)) .setDefaultStrokeColor(ThemeStore.textColorSecondary(context))
.setSelectedStrokeColor(ThemeStore.accentColor(context)) .setSelectedStrokeColor(ThemeStore.accentColor(context))
.setPressedBgColor(context.resources.getColor(R.color.transparent30)) .setPressedBgColor(context.getCompatColor(R.color.transparent30))
.create() .create()
setTextColor( setTextColor(
Selector.colorBuild() Selector.colorBuild()
.setDefaultColor(ThemeStore.textColorSecondary(context)) .setDefaultColor(ThemeStore.textColorSecondary(context))
.setSelectedColor(ThemeStore.accentColor(context)) .setSelectedColor(ThemeStore.accentColor(context))
.setDisabledColor(context.resources.getColor(R.color.md_grey_500)) .setDisabledColor(context.getCompatColor(R.color.md_grey_500))
.create() .create()
) )
} }

@ -6,7 +6,8 @@ import io.legado.app.lib.webdav.http.HttpAuth
import okhttp3.Credentials import okhttp3.Credentials
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.Jsoup import org.jsoup.Jsoup
import java.io.File import java.io.File
@ -132,11 +133,11 @@ constructor(url: String) {
.url(url) .url(url)
// 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性 // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性
// 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。
.method("PROPFIND", RequestBody.create("text/plain".toMediaTypeOrNull(), requestPropsStr)) .method("PROPFIND", requestPropsStr.toRequestBody("text/plain".toMediaTypeOrNull()))
HttpAuth.auth?.let { request.header("Authorization", Credentials.basic(it.user, it.pass)) } HttpAuth.auth?.let { request.header("Authorization", Credentials.basic(it.user, it.pass)) }
request.header("Depth", if (depth < 0) "infinity" else Integer.toString(depth)) request.header("Depth", if (depth < 0) "infinity" else depth.toString())
return okHttpClient.newCall(request.build()).execute() return okHttpClient.newCall(request.build()).execute()
} }
@ -212,7 +213,7 @@ constructor(url: String) {
if (!file.exists()) return false if (!file.exists()) return false
val mediaType = contentType?.toMediaTypeOrNull() val mediaType = contentType?.toMediaTypeOrNull()
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
val fileBody = RequestBody.create(mediaType, file) val fileBody = file.asRequestBody(mediaType)
getUrl()?.let { getUrl()?.let {
val request = Request.Builder() val request = Request.Builder()
.url(it) .url(it)

@ -19,8 +19,8 @@ import io.legado.app.constant.Bus
import io.legado.app.constant.Status import io.legado.app.constant.Status
import io.legado.app.help.IntentDataHelp import io.legado.app.help.IntentDataHelp
import io.legado.app.help.MediaHelp import io.legado.app.help.MediaHelp
import io.legado.app.help.PendingIntentHelp
import io.legado.app.receiver.MediaButtonReceiver import io.legado.app.receiver.MediaButtonReceiver
import io.legado.app.ui.readbook.ReadBookActivity
import io.legado.app.ui.widget.page.TextChapter import io.legado.app.ui.widget.page.TextChapter
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean
import io.legado.app.utils.postEvent import io.legado.app.utils.postEvent
@ -32,80 +32,6 @@ abstract class BaseReadAloudService : BaseService(),
var isRun = false var isRun = false
var timeMinute: Int = 0 var timeMinute: Int = 0
fun play(
context: Context,
title: String,
subtitle: String,
pageIndex: Int,
dataKey: String,
play: Boolean = true
) {
val readAloudIntent = Intent(context, TTSReadAloudService::class.java)
readAloudIntent.action = Action.play
readAloudIntent.putExtra("title", title)
readAloudIntent.putExtra("subtitle", subtitle)
readAloudIntent.putExtra("pageIndex", pageIndex)
readAloudIntent.putExtra("dataKey", dataKey)
readAloudIntent.putExtra("play", play)
context.startService(readAloudIntent)
}
fun pause(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.pause
context.startService(intent)
}
}
fun resume(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.resume
context.startService(intent)
}
}
fun stop(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.stop
context.startService(intent)
}
}
fun prevParagraph(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.prevParagraph
context.startService(intent)
}
}
fun nextParagraph(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.nextParagraph
context.startService(intent)
}
}
fun upTtsSpeechRate(context: Context) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.upTtsSpeechRate
context.startService(intent)
}
}
fun setTimer(context: Context, minute: Int) {
if (isRun) {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = Action.setTimer
intent.putExtra("minute", minute)
context.startService(intent)
}
}
} }
private val handler = Handler() private val handler = Handler()
@ -361,29 +287,29 @@ abstract class BaseReadAloudService : BaseService(),
.setOngoing(true) .setOngoing(true)
.setContentTitle(nTitle) .setContentTitle(nTitle)
.setContentText(nSubtitle) .setContentText(nSubtitle)
.setContentIntent(PendingIntentHelp.readBookActivityPendingIntent(this)) .setContentIntent(readBookActivityPendingIntent(this))
if (pause) { if (pause) {
builder.addAction( builder.addAction(
R.drawable.ic_play_24dp, R.drawable.ic_play_24dp,
getString(R.string.resume), getString(R.string.resume),
PendingIntentHelp.aloudServicePendingIntent(this, Action.resume) aloudServicePendingIntent(this, Action.resume)
) )
} else { } else {
builder.addAction( builder.addAction(
R.drawable.ic_pause_24dp, R.drawable.ic_pause_24dp,
getString(R.string.pause), getString(R.string.pause),
PendingIntentHelp.aloudServicePendingIntent(this, Action.pause) aloudServicePendingIntent(this, Action.pause)
) )
} }
builder.addAction( builder.addAction(
R.drawable.ic_stop_black_24dp, R.drawable.ic_stop_black_24dp,
getString(R.string.stop), getString(R.string.stop),
PendingIntentHelp.aloudServicePendingIntent(this, Action.stop) aloudServicePendingIntent(this, Action.stop)
) )
builder.addAction( builder.addAction(
R.drawable.ic_time_add_24dp, R.drawable.ic_time_add_24dp,
getString(R.string.set_timer), getString(R.string.set_timer),
PendingIntentHelp.aloudServicePendingIntent(this, Action.addTimer) aloudServicePendingIntent(this, Action.addTimer)
) )
builder.setStyle( builder.setStyle(
androidx.media.app.NotificationCompat.MediaStyle() androidx.media.app.NotificationCompat.MediaStyle()
@ -394,4 +320,16 @@ abstract class BaseReadAloudService : BaseService(),
val notification = builder.build() val notification = builder.build()
startForeground(112201, notification) startForeground(112201, notification)
} }
fun readBookActivityPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, ReadBookActivity::class.java)
intent.action = "readBookActivity"
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
fun aloudServicePendingIntent(context: Context, actionStr: String): PendingIntent {
val intent = Intent(context, TTSReadAloudService::class.java)
intent.action = actionStr
return PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
} }

@ -20,6 +20,7 @@ import io.legado.app.constant.Status
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.help.IntentDataHelp import io.legado.app.help.IntentDataHelp
import io.legado.app.help.ReadAloud
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.noButton
@ -190,7 +191,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
when (keyCode) { when (keyCode) {
KeyEvent.KEYCODE_BACK -> { KeyEvent.KEYCODE_BACK -> {
if (readAloudStatus == Status.PLAY) { if (readAloudStatus == Status.PLAY) {
BaseReadAloudService.pause(this) ReadAloud.pause(this)
toast(R.string.read_aloud_pause) toast(R.string.read_aloud_pause)
return true return true
} }
@ -450,8 +451,8 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
} }
when (readAloudStatus) { when (readAloudStatus) {
Status.STOP -> readAloud() Status.STOP -> readAloud()
Status.PLAY -> BaseReadAloudService.pause(this) Status.PLAY -> ReadAloud.pause(this)
Status.PAUSE -> BaseReadAloudService.resume(this) Status.PAUSE -> ReadAloud.resume(this)
} }
} }
@ -464,7 +465,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
if (book != null && textChapter != null) { if (book != null && textChapter != null) {
val key = System.currentTimeMillis().toString() val key = System.currentTimeMillis().toString()
IntentDataHelp.putData(key, textChapter) IntentDataHelp.putData(key, textChapter)
BaseReadAloudService.play( ReadAloud.play(
this, book.name, textChapter.title, this, book.name, textChapter.title,
viewModel.durPageIndex, key, play viewModel.durPageIndex, key, play
) )
@ -569,7 +570,7 @@ class ReadBookActivity : VMBaseActivity<ReadBookViewModel>(R.layout.activity_rea
page_view.upContent() page_view.upContent()
viewModel.saveRead() viewModel.saveRead()
} }
2 -> if (!moveToNextChapter()) BaseReadAloudService.stop(this) 2 -> if (!moveToNextChapter()) ReadAloud.stop(this)
-1 -> { -1 -> {
if (viewModel.durPageIndex > 0) { if (viewModel.durPageIndex > 0) {
viewModel.durPageIndex = viewModel.durPageIndex - 1 viewModel.durPageIndex = viewModel.durPageIndex - 1

@ -10,8 +10,8 @@ import io.legado.app.constant.BookType
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.ReadAloud
import io.legado.app.model.WebBook import io.legado.app.model.WebBook
import io.legado.app.service.BaseReadAloudService
import io.legado.app.ui.widget.page.TextChapter import io.legado.app.ui.widget.page.TextChapter
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
@ -332,7 +332,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) {
override fun onCleared() { override fun onCleared() {
super.onCleared() super.onCleared()
BaseReadAloudService.stop(context) ReadAloud.stop(context)
} }
interface CallBack { interface CallBack {

@ -11,6 +11,7 @@ import androidx.fragment.app.DialogFragment
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.Bus import io.legado.app.constant.Bus
import io.legado.app.constant.Status import io.legado.app.constant.Status
import io.legado.app.help.ReadAloud
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.ui.readbook.Help import io.legado.app.ui.readbook.Help
import io.legado.app.utils.* import io.legado.app.utils.*
@ -104,7 +105,7 @@ class ReadAloudDialog : DialogFragment() {
override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
override fun onStopTrackingTouch(seekBar: SeekBar?) { override fun onStopTrackingTouch(seekBar: SeekBar?) {
BaseReadAloudService.setTimer(requireContext(), seek_timer.progress) ReadAloud.setTimer(requireContext(), seek_timer.progress)
} }
}) })
} }
@ -112,11 +113,11 @@ class ReadAloudDialog : DialogFragment() {
private fun initOnClick() { private fun initOnClick() {
iv_menu.onClick { callBack?.showMenu(); dismiss() } iv_menu.onClick { callBack?.showMenu(); dismiss() }
iv_menu.onLongClick { callBack?.openChapterList(); true } iv_menu.onLongClick { callBack?.openChapterList(); true }
iv_stop.onClick { BaseReadAloudService.stop(requireContext()); dismiss() } iv_stop.onClick { ReadAloud.stop(requireContext()); dismiss() }
iv_play_pause.onClick { postEvent(Bus.READ_ALOUD_BUTTON, true) } iv_play_pause.onClick { postEvent(Bus.READ_ALOUD_BUTTON, true) }
iv_play_prev.onClick { BaseReadAloudService.prevParagraph(requireContext()) } iv_play_prev.onClick { ReadAloud.prevParagraph(requireContext()) }
iv_play_prev.onLongClick { postEvent(Bus.TTS_TURN_PAGE, -2); true } iv_play_prev.onLongClick { postEvent(Bus.TTS_TURN_PAGE, -2); true }
iv_play_next.onClick { BaseReadAloudService.nextParagraph(requireContext()) } iv_play_next.onClick { ReadAloud.nextParagraph(requireContext()) }
iv_play_next.onLongClick { postEvent(Bus.TTS_TURN_PAGE, 2); true } iv_play_next.onLongClick { postEvent(Bus.TTS_TURN_PAGE, 2); true }
} }
@ -129,10 +130,10 @@ class ReadAloudDialog : DialogFragment() {
} }
private fun upTtsSpeechRate() { private fun upTtsSpeechRate() {
BaseReadAloudService.upTtsSpeechRate(requireContext()) ReadAloud.upTtsSpeechRate(requireContext())
if (callBack?.readAloudStatus == Status.PLAY) { if (callBack?.readAloudStatus == Status.PLAY) {
BaseReadAloudService.pause(requireContext()) ReadAloud.pause(requireContext())
BaseReadAloudService.resume(requireContext()) ReadAloud.resume(requireContext())
} }
} }

@ -18,6 +18,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import io.legado.app.R import io.legado.app.R
import io.legado.app.utils.getCompatColor
import kotlin.math.min import kotlin.math.min
import kotlin.math.pow import kotlin.math.pow
@ -190,7 +191,7 @@ class CircleImageView : AppCompatImageView {
} }
fun setCircleBackgroundColorResource(@ColorRes circleBackgroundRes: Int) { fun setCircleBackgroundColorResource(@ColorRes circleBackgroundRes: Int) {
circleBackgroundColor = context.resources.getColor(circleBackgroundRes) circleBackgroundColor = context.getCompatColor(circleBackgroundRes)
} }
override fun setImageBitmap(bm: Bitmap) { override fun setImageBitmap(bm: Bitmap) {

Loading…
Cancel
Save