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 { object Bus {
const val RECREATE = "RECREATE" const val RECREATE = "RECREATE"
const val UP_BOOK = "sourceDebugLog" 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 package io.legado.app.service
import android.app.PendingIntent import android.app.PendingIntent
import android.content.ComponentName import android.content.*
import android.content.Context import android.graphics.BitmapFactory
import android.content.Intent
import android.media.AudioAttributes import android.media.AudioAttributes
import android.media.AudioFocusRequest import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
@ -11,9 +10,16 @@ import android.os.Build
import android.speech.tts.TextToSpeech import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener import android.speech.tts.UtteranceProgressListener
import android.support.v4.media.session.MediaSessionCompat 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.R
import io.legado.app.base.BaseService 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.receiver.MediaButtonIntentReceiver
import io.legado.app.utils.postEvent
import io.legado.app.utils.toast import io.legado.app.utils.toast
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.* import java.util.*
@ -21,8 +27,16 @@ import java.util.*
class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManager.OnAudioFocusChangeListener { class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManager.OnAudioFocusChangeListener {
companion object { companion object {
val tag = ReadAloudService::class.java.simpleName val tag: String = ReadAloudService::class.java.simpleName
var isRun = false 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) { 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 textToSpeech: TextToSpeech? = null
private var ttsIsSuccess: Boolean = false private var ttsIsSuccess: Boolean = false
private lateinit var audioManager: AudioManager private lateinit var audioManager: AudioManager
private lateinit var mFocusRequest: AudioFocusRequest private lateinit var mFocusRequest: AudioFocusRequest
private var mediaSessionCompat: MediaSessionCompat? = null 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() { override fun onCreate() {
super.onCreate() super.onCreate()
@ -65,12 +88,15 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
initFocusRequest() initFocusRequest()
initMediaSession() initMediaSession()
initBroadcastReceiver()
upMediaSessionPlaybackState()
upNotification()
} }
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
isRun = false isRun = false
unregisterReceiver(broadcastReceiver)
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 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 音频焦点 * @return 音频焦点
*/ */
@ -162,6 +219,18 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED 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) { override fun onAudioFocusChange(focusChange: Int) {
when (focusChange) { when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> { 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