pull/32/head
kunfei 6 years ago
parent 830f485188
commit 124d8e8dbd
  1. 4
      app/build.gradle
  2. 55
      app/src/main/java/io/legado/app/receiver/MediaButtonIntentReceiver.kt
  3. 67
      app/src/main/java/io/legado/app/service/ReadAloudService.kt

@ -79,11 +79,12 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
//androidX //androidX
implementation 'androidx.core:core-ktx:1.2.0-alpha02' implementation 'androidx.core:core-ktx:1.2.0-alpha03'
implementation 'androidx.appcompat:appcompat:1.1.0-rc01' implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.preference:preference:1.1.0-rc01' implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'androidx.media:media:1.1.0-rc01'
implementation 'com.google.android.material:material:1.1.0-alpha09' implementation 'com.google.android.material:material:1.1.0-alpha09'
implementation 'com.google.android:flexbox:1.1.0' implementation 'com.google.android:flexbox:1.1.0'
@ -134,4 +135,5 @@ dependencies {
// //
implementation 'com.jaredrummler:colorpicker:1.1.0' implementation 'com.jaredrummler:colorpicker:1.1.0'
} }

@ -0,0 +1,55 @@
package io.legado.app.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.view.KeyEvent
/**
* Created by GKF on 2018/1/6.
* 监听耳机键
*/
class MediaButtonIntentReceiver : BroadcastReceiver() {
companion object {
val TAG = MediaButtonIntentReceiver::class.java.simpleName
fun handleIntent(context: Context, intent: Intent): Boolean {
val intentAction = intent.action
if (Intent.ACTION_MEDIA_BUTTON == intentAction) {
val event = intent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT) ?: return false
val keycode = event.keyCode
val action = event.action
val command: String? = null
when (keycode) {
KeyEvent.KEYCODE_MEDIA_STOP, KeyEvent.KEYCODE_MEDIA_PAUSE, KeyEvent.KEYCODE_MEDIA_PLAY, KeyEvent.KEYCODE_HEADSETHOOK, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> {
}
else -> {
}
}// command = ReadAloudService.ActionMediaButton;
if (command != null) {
if (action == KeyEvent.ACTION_DOWN) {
readAloud(context, command)
return true
}
}
}
return false
}
private fun readAloud(context: Context, command: String?) {
}
}
override fun onReceive(context: Context, intent: Intent) {
if (handleIntent(context, intent) && isOrderedBroadcast) {
abortBroadcast()
}
}
}

@ -1,12 +1,19 @@
package io.legado.app.service package io.legado.app.service
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
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 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.receiver.MediaButtonIntentReceiver
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.*
@ -14,6 +21,7 @@ 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
var isRun = false var isRun = false
fun paly(context: Context, title: String, body: String) { fun paly(context: Context, title: String, body: String) {
@ -46,11 +54,17 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
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 mFocusRequest: AudioFocusRequest
private var mediaSessionCompat: MediaSessionCompat? = null
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
isRun = true isRun = true
textToSpeech = TextToSpeech(this, this) textToSpeech = TextToSpeech(this, this)
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
initFocusRequest()
initMediaSession()
} }
@ -96,12 +110,63 @@ class ReadAloudService : BaseService(), TextToSpeech.OnInitListener, AudioManage
} }
} }
/**
* 初始化MediaSession
*/
private fun initMediaSession() {
val mComponent = ComponentName(packageName, MediaButtonIntentReceiver::class.java.name)
val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
mediaButtonIntent.component = mComponent
val mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(
this, 0,
mediaButtonIntent, PendingIntent.FLAG_CANCEL_CURRENT
)
mediaSessionCompat = MediaSessionCompat(this, tag, mComponent, mediaButtonReceiverPendingIntent)
mediaSessionCompat?.setCallback(object : MediaSessionCompat.Callback() {
override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
return MediaButtonIntentReceiver.handleIntent(this@ReadAloudService, mediaButtonEvent)
}
})
mediaSessionCompat?.setMediaButtonReceiver(mediaButtonReceiverPendingIntent)
}
private fun initFocusRequest() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val mPlaybackAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
mFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(mPlaybackAttributes)
.setAcceptsDelayedFocusGain(true)
.setOnAudioFocusChangeListener(this)
.build()
}
}
/**
* @return 音频焦点
*/
private fun requestFocus(): Boolean {
val request: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioManager.requestAudioFocus(mFocusRequest)
} else {
@Suppress("DEPRECATION")
audioManager.requestAudioFocus(
this,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
)
}
return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
}
override fun onAudioFocusChange(focusChange: Int) { override fun onAudioFocusChange(focusChange: Int) {
when (focusChange) { when (focusChange) {
AudioManager.AUDIOFOCUS_GAIN -> { AudioManager.AUDIOFOCUS_GAIN -> {
// 重新获得焦点, 可做恢复播放,恢复后台音量的操作 // 重新获得焦点, 可做恢复播放,恢复后台音量的操作
} }
AudioManager.AUDIOFOCUS_LOSS -> { AudioManager.AUDIOFOCUS_LOSS -> {
// 永久丢失焦点除非重新主动获取,这种情况是被其他播放器抢去了焦点, 为避免与其他播放器混音,可将音乐暂停 // 永久丢失焦点除非重新主动获取,这种情况是被其他播放器抢去了焦点, 为避免与其他播放器混音,可将音乐暂停
} }

Loading…
Cancel
Save