Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature: Use the android TTS feature to speech messages #1813

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Moez Bhatti <[email protected]>
* Copyright (C) 2017,2021 Moez Bhatti <[email protected]>,to268
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should i add my real name and my email address instead ?

*
* This file is part of QKSMS.
*
Expand Down Expand Up @@ -30,7 +30,9 @@ import android.os.Build
import android.os.Bundle
import android.provider.ContactsContract
import android.provider.MediaStore
import android.speech.tts.TextToSpeech
import android.text.format.DateFormat
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.AlertDialog
Expand Down Expand Up @@ -66,12 +68,16 @@ import io.reactivex.Observable
import io.reactivex.subjects.PublishSubject
import io.reactivex.subjects.Subject
import kotlinx.android.synthetic.main.compose_activity.*
import kotlinx.android.synthetic.main.compose_activity.attachments
import kotlinx.android.synthetic.main.compose_activity.sim
import kotlinx.android.synthetic.main.compose_activity.simIndex
import kotlinx.android.synthetic.main.message_list_item_in.*
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
import kotlin.collections.HashMap

class ComposeActivity : QkThemedActivity(), ComposeView {
class ComposeActivity : QkThemedActivity(), ComposeView, TextToSpeech.OnInitListener {

companion object {
private const val SelectContactRequestCode = 0
Expand All @@ -82,12 +88,18 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
private const val CameraDestinationKey = "camera_destination"
}

@Inject lateinit var attachmentAdapter: AttachmentAdapter
@Inject lateinit var chipsAdapter: ChipsAdapter
@Inject lateinit var dateFormatter: DateFormatter
@Inject lateinit var messageAdapter: MessagesAdapter
@Inject lateinit var navigator: Navigator
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject
lateinit var attachmentAdapter: AttachmentAdapter
@Inject
lateinit var chipsAdapter: ChipsAdapter
@Inject
lateinit var dateFormatter: DateFormatter
@Inject
lateinit var messageAdapter: MessagesAdapter
@Inject
lateinit var navigator: Navigator
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

override val activityVisibleIntent: Subject<Boolean> = PublishSubject.create()
override val chipsSelectedIntent: Subject<HashMap<String, String?>> = PublishSubject.create()
Expand Down Expand Up @@ -119,6 +131,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
private val viewModel by lazy { ViewModelProviders.of(this, viewModelFactory)[ComposeViewModel::class.java] }

private var cameraDestination: Uri? = null
private var tts: TextToSpeech? = null

override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
Expand Down Expand Up @@ -160,6 +173,9 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
if (Build.VERSION.SDK_INT <= 22) {
messageBackground.setBackgroundTint(resolveThemeColor(R.attr.bubbleColor))
}

// Set tts info
tts = TextToSpeech(this, this)
}

override fun onStart() {
Expand Down Expand Up @@ -206,6 +222,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
toolbar.menu.findItem(R.id.details)?.isVisible = !state.editingMode && state.selectedMessages == 1
toolbar.menu.findItem(R.id.delete)?.isVisible = !state.editingMode && state.selectedMessages > 0
toolbar.menu.findItem(R.id.forward)?.isVisible = !state.editingMode && state.selectedMessages == 1
toolbar.menu.findItem(R.id.speech)?.isVisible = !state.editingMode && state.selectedMessages == 1
toolbar.menu.findItem(R.id.previous)?.isVisible = state.selectedMessages == 0 && state.query.isNotEmpty()
toolbar.menu.findItem(R.id.next)?.isVisible = state.selectedMessages == 0 && state.query.isNotEmpty()
toolbar.menu.findItem(R.id.clear)?.isVisible = state.selectedMessages == 0 && state.query.isNotEmpty()
Expand Down Expand Up @@ -251,6 +268,10 @@ class ComposeActivity : QkThemedActivity(), ComposeView {
.show()
}

override fun speechText(text: String) {
tts!!.speak(text, TextToSpeech.QUEUE_FLUSH, null, "")
}

override fun requestDefaultSms() {
navigator.showDefaultSmsDialog(this)
}
Expand Down Expand Up @@ -399,4 +420,27 @@ class ComposeActivity : QkThemedActivity(), ComposeView {

override fun onBackPressed() = backPressedIntent.onNext(Unit)

// Text to speech
override fun onInit(status: Int) {
if (status == TextToSpeech.SUCCESS) {
val result = tts!!.setLanguage(Locale.getDefault())

if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "The default language is not supported !")
}

} else {
Log.e("TTS", "Initialization failed !")
}
}

override fun onDestroy() {
if (tts != null) {
tts!!.stop()
tts!!.shutdown()
}

super.onDestroy()
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ interface ComposeView : QkView<ComposeState> {

fun clearSelection()
fun showDetails(details: String)
fun speechText(text: String)
fun requestDefaultSms()
fun requestStoragePermission()
fun requestSmsPermission()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017 Moez Bhatti <[email protected]>
* Copyright (C) 2017,2021 Moez Bhatti <[email protected]>,to268
*
* This file is part of QKSMS.
*
Expand Down Expand Up @@ -74,29 +74,29 @@ import javax.inject.Inject
import javax.inject.Named

class ComposeViewModel @Inject constructor(
@Named("query") private val query: String,
@Named("threadId") private val threadId: Long,
@Named("addresses") private val addresses: List<String>,
@Named("text") private val sharedText: String,
@Named("attachments") private val sharedAttachments: Attachments,
private val contactRepo: ContactRepository,
private val context: Context,
private val activeConversationManager: ActiveConversationManager,
private val addScheduledMessage: AddScheduledMessage,
private val billingManager: BillingManager,
private val cancelMessage: CancelDelayedMessage,
private val conversationRepo: ConversationRepository,
private val deleteMessages: DeleteMessages,
private val markRead: MarkRead,
private val messageDetailsFormatter: MessageDetailsFormatter,
private val messageRepo: MessageRepository,
private val navigator: Navigator,
private val permissionManager: PermissionManager,
private val phoneNumberUtils: PhoneNumberUtils,
private val prefs: Preferences,
private val retrySending: RetrySending,
private val sendMessage: SendMessage,
private val subscriptionManager: SubscriptionManagerCompat
@Named("query") private val query: String,
@Named("threadId") private val threadId: Long,
@Named("addresses") private val addresses: List<String>,
@Named("text") private val sharedText: String,
@Named("attachments") private val sharedAttachments: Attachments,
private val contactRepo: ContactRepository,
private val context: Context,
private val activeConversationManager: ActiveConversationManager,
private val addScheduledMessage: AddScheduledMessage,
private val billingManager: BillingManager,
private val cancelMessage: CancelDelayedMessage,
private val conversationRepo: ConversationRepository,
private val deleteMessages: DeleteMessages,
private val markRead: MarkRead,
private val messageDetailsFormatter: MessageDetailsFormatter,
private val messageRepo: MessageRepository,
private val navigator: Navigator,
private val permissionManager: PermissionManager,
private val phoneNumberUtils: PhoneNumberUtils,
private val prefs: Preferences,
private val retrySending: RetrySending,
private val sendMessage: SendMessage,
private val subscriptionManager: SubscriptionManagerCompat
) : QkViewModel<ComposeView, ComposeState>(ComposeState(
editingMode = threadId == 0L && addresses.isEmpty(),
threadId = threadId,
Expand Down Expand Up @@ -340,6 +340,16 @@ class ComposeViewModel @Inject constructor(
.autoDisposable(view.scope())
.subscribe { view.showDetails(it) }

// Speech text
view.optionsItemIntent
.filter { it == R.id.speech }
.withLatestFrom(view.messagesSelectedIntent) { _, messages -> messages }
.mapNotNull { messages -> messages.firstOrNull().also { view.clearSelection() } }
.mapNotNull(messageRepo::getMessage)
.mapNotNull(Message::getText)
.autoDisposable(view.scope())
.subscribe { view.speechText(it) }

// Delete the messages
view.optionsItemIntent
.filter { it == R.id.delete }
Expand Down
30 changes: 30 additions & 0 deletions presentation/src/main/res/drawable/ic_speech_black_24dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
~ Copyright (C) 2021 to268
~
~ This file is part of QKSMS.
~
~ QKSMS is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ QKSMS is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M9,9m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"/>
<path
android:fillColor="#FF000000"
android:pathData="M9,15c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4zM16.76,5.36l-1.68,1.69c0.84,1.18 0.84,2.71 0,3.89l1.68,1.69c2.02,-2.02 2.02,-5.07 0,-7.27zM20.07,2l-1.63,1.63c2.77,3.02 2.77,7.56 0,10.74L20.07,16c3.9,-3.89 3.91,-9.95 0,-14z"/>
</vector>
9 changes: 8 additions & 1 deletion presentation/src/main/res/menu/compose.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 Moez Bhatti <[email protected]>
~ Copyright (C) 2019,2021 Moez Bhatti <[email protected]>,to268
~
~ This file is part of QKSMS.
~
Expand Down Expand Up @@ -69,6 +69,13 @@
android:visible="false"
app:showAsAction="ifRoom" />

<item
android:id="@+id/speech"
android:icon="@drawable/ic_speech_black_24dp"
android:title="@string/compose_menu_speech"
android:visible="false"
app:showAsAction="ifRoom" />

<item
android:id="@+id/previous"
android:icon="@drawable/ic_keyboard_arrow_up_black_24dp"
Expand Down
3 changes: 2 additions & 1 deletion presentation/src/main/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 Moez Bhatti <[email protected]>
~ Copyright (C) 2019,2021 Moez Bhatti <[email protected]>,to268
~
~ This file is part of QKSMS.
~
Expand Down Expand Up @@ -102,6 +102,7 @@
<string name="compose_hint">Écrire un message&#8230;</string>
<string name="compose_menu_copy">Copier le texte</string>
<string name="compose_menu_forward">Transférer</string>
<string name="compose_menu_speech">Énoncer le texte</string>
<string name="compose_menu_delete">Supprimer</string>
<string name="compose_menu_previous">Précédent</string>
<string name="compose_menu_next">Suivant</string>
Expand Down
5 changes: 3 additions & 2 deletions presentation/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
~ Copyright (C) 2019 Moez Bhatti <[email protected]>
~ Copyright (C) 2019,2021 Moez Bhatti <[email protected]>,to268
~
~ This file is part of QKSMS.
~
Expand Down Expand Up @@ -116,6 +116,7 @@
<string name="compose_hint">Write a message…</string>
<string name="compose_menu_copy">Copy text</string>
<string name="compose_menu_forward">Forward</string>
<string name="compose_menu_speech" translatable="false">Speech text</string>
<string name="compose_menu_delete">Delete</string>
<string name="compose_menu_previous">Previous</string>
<string name="compose_menu_next">Next</string>
Expand Down Expand Up @@ -382,7 +383,7 @@
<string name="about_changelog" translatable="false">https://github.com/moezbhatti/qksms/releases</string>
<string name="about_contact" translatable="false">[email protected]</string>
<string name="about_license" translatable="false">GNU General Public License v3.0</string>
<string name="about_copyright" translatable="false">© 2014–2019</string>
<string name="about_copyright" translatable="false">© 2014–2021</string>

<string name="changelog_title" translatable="false">New in QKSMS</string>
<string name="changelog_version" translatable="false">Version %s</string>
Expand Down