From 3d837f1430d6ce5fd01d91b77486a1955610e8d4 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Fri, 16 Jun 2023 12:30:06 +0530 Subject: [PATCH 1/2] Fixes of Text to Speech init failed on android 13 --- core/src/main/AndroidManifest.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 25f429db5..d0b1896f4 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -18,6 +18,13 @@ + + + + + + + Date: Mon, 19 Jun 2023 19:20:24 +0530 Subject: [PATCH 2/2] Enhanced the TTS feature. Now, during the screen launch, we only set up the TTS service with the WebView. This is necessary to configure the JavaScript interface when the WebView is created. Otherwise, the JavaScript interface is not recognized. We initialize the TTS feature when the user tries to use it for better optimization. --- .../core/main/CoreReaderFragment.kt | 33 +++++++++++++++++-- .../core/main/KiwixTextToSpeech.kt | 31 ++++++++++------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt index be54dc552..1e188a83f 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreReaderFragment.kt @@ -326,6 +326,7 @@ abstract class CoreReaderFragment : private lateinit var serviceConnection: ServiceConnection private var readAloudService: ReadAloudService? = null private var navigationHistoryList: MutableList = ArrayList() + private var isReadSelection = false private var storagePermissionForNotesLauncher: ActivityResultLauncher? = registerForActivityResult( @@ -366,7 +367,12 @@ abstract class CoreReaderFragment : protected open fun configureWebViewSelectionHandler(menu: Menu?) { menu?.findItem(R.id.menu_speak_text)?.setOnMenuItemClickListener { - getCurrentWebView()?.let { currentWebView -> tts?.readSelection(currentWebView) } + if (tts?.isInitialized == false) { + isReadSelection = true + tts?.initializeTTS() + } else { + startReadSelection() + } actionMode?.finish() true } @@ -853,7 +859,11 @@ abstract class CoreReaderFragment : requireActivity(), object : OnInitSucceedListener { override fun onInitSucceed() { - // do nothing it's default override method + if (isReadSelection) { + startReadSelection() + } else { + startReadAloud() + } } }, object : OnSpeakingListener { @@ -900,6 +910,18 @@ abstract class CoreReaderFragment : } } + private fun startReadAloud() { + getCurrentWebView()?.let { + tts?.readAloud(it) + } + } + + private fun startReadSelection() { + getCurrentWebView()?.let { + tts?.readSelection(it) + } + } + @OnClick(R2.id.activity_main_button_pause_tts) fun pauseTts() { if (tts?.currentTTSTask == null) { @@ -1130,7 +1152,12 @@ abstract class CoreReaderFragment : if (isBackToTopEnabled) { backToTopButton?.hide() } - getCurrentWebView()?.let { tts?.readAloud(it) } + if (tts?.isInitialized == false) { + isReadSelection = false + tts?.initializeTTS() + } else { + startReadAloud() + } } View.VISIBLE -> { if (isBackToTopEnabled) { diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.kt index 3d5078887..38484ff9e 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/KiwixTextToSpeech.kt @@ -28,7 +28,6 @@ import android.speech.tts.TextToSpeech import android.speech.tts.TextToSpeech.Engine import android.speech.tts.TextToSpeech.LANG_MISSING_DATA import android.speech.tts.TextToSpeech.LANG_NOT_SUPPORTED -import android.speech.tts.TextToSpeech.OnInitListener import android.speech.tts.TextToSpeech.QUEUE_ADD import android.speech.tts.TextToSpeech.SUCCESS import android.speech.tts.UtteranceProgressListener @@ -36,7 +35,6 @@ import android.util.Log import android.webkit.JavascriptInterface import android.webkit.WebView import android.widget.Toast -import org.kiwix.kiwixmobile.core.CoreApp.Companion.instance import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.extensions.toast import org.kiwix.kiwixmobile.core.reader.ZimReaderContainer @@ -54,7 +52,7 @@ import java.util.concurrent.atomic.AtomicInteger */ class KiwixTextToSpeech internal constructor( val context: Context, - onInitSucceedListener: OnInitSucceedListener, + private val onInitSucceedListener: OnInitSucceedListener, val onSpeakingListener: OnSpeakingListener, private var onAudioFocusChangeListener: OnAudioFocusChangeListener? = null, private val zimReaderContainer: ZimReaderContainer @@ -63,26 +61,35 @@ class KiwixTextToSpeech internal constructor( private val focusLock: Any = Any() private val am: AudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager @JvmField var currentTTSTask: TTSTask? = null - private val tts: TextToSpeech = TextToSpeech( - instance, - OnInitListener { status: Int -> - if (status == SUCCESS) { + private lateinit var tts: TextToSpeech + + /** + * Initializes the TextToSpeech object. + */ + fun initializeTTS() { + tts = TextToSpeech( + context + ) { status: Int -> + if (status == TextToSpeech.SUCCESS) { Log.d(TAG_KIWIX, "TextToSpeech was initialized successfully.") this.isInitialized = true onInitSucceedListener.onInitSucceed() } else { Log.e(TAG_KIWIX, "Initialization of TextToSpeech Failed!") - context.toast(R.string.texttospeech_initialization_failed, Toast.LENGTH_SHORT) + context.toast( + R.string.texttospeech_initialization_failed, + Toast.LENGTH_SHORT + ) } } - ) + } /** * Returns whether the TTS is initialized. * * @return `true` if TTS is initialized; `false` otherwise */ - private var isInitialized = false + var isInitialized = false init { Log.d(TAG_KIWIX, "Initializing TextToSpeech") @@ -214,7 +221,9 @@ class KiwixTextToSpeech internal constructor( * {@link https://developer.android.com/guide/topics/media-apps/audio-focus#audio-focus-change } */ fun shutdown() { - tts.shutdown() + if (::tts.isInitialized) { + tts.shutdown() + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { focusRequest?.let(am::abandonAudioFocusRequest) focusRequest = null