修复低版本Android使用TTS闪退。

移除maven { url "https://github.com/psiegman/mvn-repo/raw/master/releases" }
更新一些androidx库
将使用Androidx版的multidex,并升级版本为2.0.1。
使用androidx.media,解决升级Android Studio后低版本使用TTS时闪退。
pull/977/head
ag2s20150909 4 years ago
parent 6bd2a41e1b
commit 0ccac4a8d1
  1. 20
      app/build.gradle
  2. 48
      app/src/main/java/io/legado/app/help/MediaHelp.kt
  3. 5
      app/src/main/java/io/legado/app/service/AudioPlayService.kt
  4. 6
      app/src/main/java/io/legado/app/service/BaseReadAloudService.kt
  5. 19
      app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt
  6. 16
      app/src/main/java/io/legado/app/utils/BitmapUtils.kt
  7. 2
      build.gradle

@ -111,20 +111,20 @@ kapt {
dependencies { dependencies {
implementation project(path: ':epublib') implementation project(path: ':epublib')
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.1' coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar']) implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.3.0' androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation "com.android.support:multidex:1.0.3" implementation 'androidx.multidex:multidex:2.0.1'
//kotlin //kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
//androidX //androidX
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
implementation "androidx.activity:activity-ktx:1.2.0" implementation "androidx.activity:activity-ktx:1.2.3"
implementation "androidx.fragment:fragment-ktx:1.3.0" implementation "androidx.fragment:fragment-ktx:1.3.3"
implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.preference:preference-ktx:1.1.1'
implementation "androidx.collection:collection-ktx:1.1.0" implementation "androidx.collection:collection-ktx:1.1.0"
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
@ -135,8 +135,9 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.code.gson:gson:2.8.6'
//media //media
def media2_version = "1.1.2" def media2_version = "1.1.3"
implementation "androidx.media2:media2-session:$media2_version" implementation "androidx.media2:media2-session:$media2_version"
implementation "androidx.media:media:1.3.1"
//implementation "androidx.media2:media2-player:$media2_version" //implementation "androidx.media2:media2-player:$media2_version"
//implementation 'com.google.android.exoplayer:exoplayer:2.13.0' //implementation 'com.google.android.exoplayer:exoplayer:2.13.0'
@ -147,8 +148,9 @@ dependencies {
implementation("com.louiscad.splitties:splitties-views:$splitties_version") implementation("com.louiscad.splitties:splitties-views:$splitties_version")
//lifecycle //lifecycle
def lifecycle_version = '2.2.0' def lifecycle_version = '2.3.1'
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" //2.3.0 lifecycle-extensions
//implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
//room //room
@ -158,13 +160,13 @@ dependencies {
testImplementation "androidx.room:room-testing:$room_version" testImplementation "androidx.room:room-testing:$room_version"
//paging //paging
implementation 'androidx.paging:paging-runtime-ktx:2.1.2' implementation 'androidx.paging:paging-runtime-ktx:3.0.0'
//liveEventBus //liveEventBus
implementation 'com.jeremyliao:live-event-bus-x:1.5.7' implementation 'com.jeremyliao:live-event-bus-x:1.5.7'
// //
def coroutines_version = '1.4.2' def coroutines_version = '1.4.3'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

@ -1,12 +1,12 @@
package io.legado.app.help package io.legado.app.help
import android.content.Context import android.content.Context
import android.media.AudioAttributes
import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
import android.media.MediaPlayer import android.media.MediaPlayer
import android.os.Build
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import androidx.media.AudioAttributesCompat
import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import io.legado.app.R import io.legado.app.R
object MediaHelp { object MediaHelp {
@ -32,20 +32,16 @@ object MediaHelp {
or PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE or PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
or PlaybackStateCompat.ACTION_SET_CAPTIONING_ENABLED) or PlaybackStateCompat.ACTION_SET_CAPTIONING_ENABLED)
fun getFocusRequest(audioFocusChangeListener: AudioManager.OnAudioFocusChangeListener): AudioFocusRequest? { fun getFocusRequest(audioFocusChangeListener: AudioManager.OnAudioFocusChangeListener): AudioFocusRequestCompat? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val mPlaybackAttributes = AudioAttributesCompat.Builder()
val mPlaybackAttributes = AudioAttributes.Builder() .setUsage(AudioAttributesCompat.USAGE_MEDIA)
.setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributesCompat.CONTENT_TYPE_MUSIC)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build()
.build() return AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(mPlaybackAttributes)
.setAudioAttributes(mPlaybackAttributes) //.setAcceptsDelayedFocusGain(true)
.setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(audioFocusChangeListener)
.setOnAudioFocusChangeListener(audioFocusChangeListener) .build()
.build()
} else {
null
}
} }
/** /**
@ -53,21 +49,11 @@ object MediaHelp {
*/ */
fun requestFocus( fun requestFocus(
audioManager: AudioManager, audioManager: AudioManager,
listener: AudioManager.OnAudioFocusChangeListener, focusRequest: AudioFocusRequestCompat?
focusRequest: AudioFocusRequest?
): Boolean { ): Boolean {
val request: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val request: Int =
focusRequest?.let { focusRequest?.let { AudioManagerCompat.requestAudioFocus(audioManager, focusRequest) }
audioManager.requestAudioFocus(focusRequest) ?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED
} ?: AudioManager.AUDIOFOCUS_REQUEST_GRANTED
} else {
@Suppress("DEPRECATION")
audioManager.requestAudioFocus(
listener,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN
)
}
return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED return request == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
} }

@ -16,6 +16,7 @@ import android.os.Looper
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.media.AudioFocusRequestCompat
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.AppConst
@ -52,7 +53,7 @@ class AudioPlayService : BaseService(),
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
private lateinit var audioManager: AudioManager private lateinit var audioManager: AudioManager
private var mFocusRequest: AudioFocusRequest? = null private var mFocusRequest: AudioFocusRequestCompat? = null
private var title: String = "" private var title: String = ""
private var subtitle: String = "" private var subtitle: String = ""
private val mediaPlayer = MediaPlayer() private val mediaPlayer = MediaPlayer()
@ -479,7 +480,7 @@ class AudioPlayService : BaseService(),
* @return 音频焦点 * @return 音频焦点
*/ */
private fun requestFocus(): Boolean { private fun requestFocus(): Boolean {
return MediaHelp.requestFocus(audioManager, this, mFocusRequest) return MediaHelp.requestFocus(audioManager, mFocusRequest)
} }
private fun thisPendingIntent(action: String): PendingIntent? { private fun thisPendingIntent(action: String): PendingIntent? {

@ -6,7 +6,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.media.AudioFocusRequest
import android.media.AudioManager import android.media.AudioManager
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
@ -14,6 +13,7 @@ import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat import android.support.v4.media.session.PlaybackStateCompat
import androidx.annotation.CallSuper import androidx.annotation.CallSuper
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.media.AudioFocusRequestCompat
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.* import io.legado.app.constant.*
@ -43,7 +43,7 @@ abstract class BaseReadAloudService : BaseService(),
internal val handler = Handler(Looper.getMainLooper()) internal val handler = Handler(Looper.getMainLooper())
private lateinit var audioManager: AudioManager private lateinit var audioManager: AudioManager
private var mFocusRequest: AudioFocusRequest? = null private var mFocusRequest: AudioFocusRequestCompat? = null
private var broadcastReceiver: BroadcastReceiver? = null private var broadcastReceiver: BroadcastReceiver? = null
private lateinit var mediaSessionCompat: MediaSessionCompat private lateinit var mediaSessionCompat: MediaSessionCompat
private var title: String = "" private var title: String = ""
@ -202,7 +202,7 @@ abstract class BaseReadAloudService : BaseService(),
* @return 音频焦点 * @return 音频焦点
*/ */
fun requestFocus(): Boolean { fun requestFocus(): Boolean {
return MediaHelp.requestFocus(audioManager, this, mFocusRequest) return MediaHelp.requestFocus(audioManager, mFocusRequest)
} }
/** /**

@ -236,15 +236,16 @@ class PageView(context: Context) : FrameLayout(context) {
} }
fun scroll(offset: Int) { fun scroll(offset: Int) {
if (offset > 0) { binding.contentTextView.scroll(offset)
for (i in 1..offset) { // if (offset > 0) {
binding.contentTextView.scroll(1) // for (i in 1..offset) {
} // binding.contentTextView.scroll(1)
} else { // }
for (i in offset..-1) { // } else {
binding.contentTextView.scroll(-1) // for (i in offset..-1) {
} // binding.contentTextView.scroll(-1)
} // }
// }
} }
fun upSelectAble(selectAble: Boolean) { fun upSelectAble(selectAble: Boolean) {

@ -29,10 +29,10 @@ object BitmapUtils {
fun decodeBitmap(path: String, width: Int, height: Int): Bitmap? { fun decodeBitmap(path: String, width: Int, height: Int): Bitmap? {
val op = BitmapFactory.Options() val op = BitmapFactory.Options()
op.inPreferredConfig = Config.RGB_565 op.inPreferredConfig = Config.RGB_565
var ips = FileInputStream(path) val ips = FileInputStream(path)
// inJustDecodeBounds如果设置为true,仅仅返回图片实际的宽和高,宽和高是赋值给opts.outWidth,opts.outHeight; // inJustDecodeBounds如果设置为true,仅仅返回图片实际的宽和高,宽和高是赋值给opts.outWidth,opts.outHeight;
op.inJustDecodeBounds = true op.inJustDecodeBounds = true
BitmapFactory.decodeStream(ips, null, op) BitmapFactory.decodeFileDescriptor(ips.fd,null,op)
//获取比例大小 //获取比例大小
val wRatio = ceil((op.outWidth / width).toDouble()).toInt() val wRatio = ceil((op.outWidth / width).toDouble()).toInt()
val hRatio = ceil((op.outHeight / height).toDouble()).toInt() val hRatio = ceil((op.outHeight / height).toDouble()).toInt()
@ -45,8 +45,8 @@ object BitmapUtils {
} }
} }
op.inJustDecodeBounds = false op.inJustDecodeBounds = false
ips = FileInputStream(path) return BitmapFactory.decodeFileDescriptor(ips.fd,null,op)
return BitmapFactory.decodeStream(ips, null, op)
} }
/** 从path中获取Bitmap图片 /** 从path中获取Bitmap图片
@ -57,14 +57,12 @@ object BitmapUtils {
val opts = BitmapFactory.Options() val opts = BitmapFactory.Options()
opts.inPreferredConfig = Config.RGB_565 opts.inPreferredConfig = Config.RGB_565
var ips = FileInputStream(path) val ips = FileInputStream(path)
opts.inJustDecodeBounds = true opts.inJustDecodeBounds = true
BitmapFactory.decodeStream(ips, null, opts) BitmapFactory.decodeFileDescriptor(ips.fd,null,opts)
opts.inSampleSize = computeSampleSize(opts, -1, 128 * 128) opts.inSampleSize = computeSampleSize(opts, -1, 128 * 128)
opts.inJustDecodeBounds = false opts.inJustDecodeBounds = false
ips = FileInputStream(path) return BitmapFactory.decodeFileDescriptor(ips.fd,null,opts)
return BitmapFactory.decodeStream(ips, null, opts)
} }
/** /**

@ -22,7 +22,7 @@ allprojects {
maven { url "https://maven.aliyun.com/nexus/content/groups/public/" } maven { url "https://maven.aliyun.com/nexus/content/groups/public/" }
maven { url "https://jitpack.io" } maven { url "https://jitpack.io" }
maven { url "https://maven.google.com/" } maven { url "https://maven.google.com/" }
maven { url "https://github.com/psiegman/mvn-repo/raw/master/releases" } //maven { url "https://github.com/psiegman/mvn-repo/raw/master/releases" }
} }
} }

Loading…
Cancel
Save