pull/32/head
kunfei 5 years ago
parent a4004d4a97
commit a353d8cbd1
  1. 1
      app/src/main/java/io/legado/app/constant/Bus.kt
  2. 5
      app/src/main/java/io/legado/app/constant/Status.kt
  3. 23
      app/src/main/java/io/legado/app/help/PendingIntentHelp.kt
  4. 135
      app/src/main/java/io/legado/app/service/ReadAloudService.kt

@ -3,4 +3,5 @@ package io.legado.app.constant
object Bus {
const val RECREATE = "RECREATE"
const val UP_BOOK = "sourceDebugLog"
const val ALOUD_STATE = "aloud_state"
}

@ -0,0 +1,5 @@
package io.legado.app.constant
object Status {
const val NEXT = 2
}

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

@ -1,9 +1,8 @@
package io.legado.app.service
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.*
import android.graphics.BitmapFactory
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager
@ -11,9 +10,16 @@ import android.os.Build
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import androidx.core.app.NotificationCompat
import io.legado.app.R
import io.legado.app.base.BaseService
import io.legado.app.constant.AppConst
import io.legado.app.constant.Bus
import io.legado.app.constant.Status
import io.legado.app.help.PendingIntentHelp
import io.legado.app.receiver.MediaButtonIntentReceiver
import io.legado.app.utils.postEvent
import io.legado.app.utils.toast
import kotlinx.coroutines.launch
import java.util.*
@ -21,8 +27,16 @@ import java.util.*
class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManager.OnAudioFocusChangeListener {
companion object {
val tag = ReadAloudService::class.java.simpleName
val tag: String = ReadAloudService::class.java.simpleName
var isRun = false
const val MEDIA_SESSION_ACTIONS = (PlaybackStateCompat.ACTION_PLAY
or PlaybackStateCompat.ACTION_PAUSE
or PlaybackStateCompat.ACTION_PLAY_PAUSE
or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
or PlaybackStateCompat.ACTION_STOP
or PlaybackStateCompat.ACTION_SEEK_TO)
fun paly(context: Context, title: String, body: String) {
}
@ -52,11 +66,20 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
}
}
private val notificationId = 112201
private var textToSpeech: TextToSpeech? = null
private var ttsIsSuccess: Boolean = false
private lateinit var audioManager: AudioManager
private lateinit var mFocusRequest: AudioFocusRequest
private var mediaSessionCompat: MediaSessionCompat? = null
private var broadcastReceiver: BroadcastReceiver? = null
private var speak: Boolean = true
private var nowSpeak: Int = 0
private val contentList = arrayListOf<String>()
private var pause = false
private var title: String = ""
private var subtitle: String = ""
private var timeMinute: Int = 0
override fun onCreate() {
super.onCreate()
@ -65,12 +88,15 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
initFocusRequest()
initMediaSession()
initBroadcastReceiver()
upMediaSessionPlaybackState()
upNotification()
}
override fun onDestroy() {
super.onDestroy()
isRun = false
unregisterReceiver(broadcastReceiver)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@ -145,6 +171,37 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
}
}
private fun initBroadcastReceiver() {
broadcastReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY == action) {
pauseReadAloud(true)
}
}
}
val intentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
registerReceiver(broadcastReceiver, intentFilter)
}
private fun pauseReadAloud(pause: Boolean) {
textToSpeech?.stop()
}
private fun resumeReadAloud() {
}
private fun playTTS() {
if (contentList.size < 1) {
postEvent(Bus.ALOUD_STATE, Status.NEXT)
return
}
if (ttsIsSuccess && !speak && requestFocus()) {
}
}
/**
* @return 音频焦点
*/
@ -162,6 +219,18 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
}
private fun upMediaSessionPlaybackState() {
mediaSessionCompat?.setPlaybackState(
PlaybackStateCompat.Builder()
.setActions(MEDIA_SESSION_ACTIONS)
.setState(
if (speak) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED,
nowSpeak.toLong(), 1f
)
.build()
)
}
override fun onAudioFocusChange(focusChange: Int) {
when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> {
@ -191,6 +260,58 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
}
}
/**
* 更新通知
*/
private fun upNotification() {
var nTitle: String = when {
pause -> getString(R.string.read_aloud_pause)
timeMinute in 1..60 -> getString(R.string.read_aloud_timer, timeMinute)
else -> getString(R.string.read_aloud_t)
}
nTitle += ": $title"
if (subtitle.isEmpty())
subtitle = getString(R.string.read_aloud_s)
val builder = NotificationCompat.Builder(this, AppConst.channelIdReadAloud)
.setSmallIcon(R.drawable.ic_volume_up)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.icon_read_book))
.setOngoing(true)
.setContentTitle(nTitle)
.setContentText(subtitle)
.setContentIntent(PendingIntentHelp.readBookActivityPendingIntent(this))
if (pause) {
builder.addAction(
R.drawable.ic_play_24dp,
getString(R.string.resume),
PendingIntentHelp.aloudServicePendingIntent(this, "resume")
)
} else {
builder.addAction(
R.drawable.ic_pause_24dp,
getString(R.string.pause),
PendingIntentHelp.aloudServicePendingIntent(this, "pause")
)
}
builder.addAction(
R.drawable.ic_stop_black_24dp,
getString(R.string.stop),
PendingIntentHelp.aloudServicePendingIntent(this, "stop")
)
builder.addAction(
R.drawable.ic_time_add_24dp,
getString(R.string.set_timer),
PendingIntentHelp.aloudServicePendingIntent(this, "setTimer")
)
builder.setStyle(
androidx.media.app.NotificationCompat.MediaStyle()
.setMediaSession(mediaSessionCompat?.sessionToken)
.setShowActionsInCompactView(0, 1, 2)
)
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
val notification = builder.build()
startForeground(notificationId, notification)
}
/**
* 朗读监听
*/
@ -208,10 +329,6 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
}
override fun onRangeStart(utteranceId: String, start: Int, end: Int, frame: Int) {
super.onRangeStart(utteranceId, start, end, frame)
}
}
}
Loading…
Cancel
Save