Continuously play tone while button is pressed

This commit is contained in:
Naveen 2022-09-02 17:20:42 +05:30
parent 60ea4ec0f3
commit a1e2684269
2 changed files with 82 additions and 36 deletions

View File

@ -1,17 +1,22 @@
package com.simplemobiletools.dialer.activities package com.simplemobiletools.dialer.activities
import android.annotation.SuppressLint
import android.annotation.TargetApi import android.annotation.TargetApi
import android.content.Intent import android.content.Intent
import android.database.Cursor import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.Telephony.Sms.Intents.SECRET_CODE_ACTION import android.provider.Telephony.Sms.Intents.SECRET_CODE_ACTION
import android.telephony.PhoneNumberUtils import android.telephony.PhoneNumberUtils
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.util.TypedValue import android.util.TypedValue
import android.view.KeyEvent import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewConfiguration
import com.reddit.indicatorfastscroll.FastScrollItemIndicator import com.reddit.indicatorfastscroll.FastScrollItemIndicator
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
@ -33,6 +38,9 @@ class DialpadActivity : SimpleActivity() {
private var hasRussianLocale = false private var hasRussianLocale = false
private var privateCursor: Cursor? = null private var privateCursor: Cursor? = null
private var toneGeneratorHelper: ToneGeneratorHelper? = null private var toneGeneratorHelper: ToneGeneratorHelper? = null
private val longPressTimeout = ViewConfiguration.getLongPressTimeout().toLong()
private val longPressHandler = Handler(Looper.getMainLooper())
private val pressedKeys = mutableSetOf<Char>()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -69,30 +77,19 @@ class DialpadActivity : SimpleActivity() {
} }
} }
dialpad_0_holder.setOnClickListener { dialpadPressed('0', it) } setupCharClick(dialpad_1_holder, '1')
dialpad_1_holder.setOnClickListener { dialpadPressed('1', it) } setupCharClick(dialpad_2_holder, '2')
dialpad_2_holder.setOnClickListener { dialpadPressed('2', it) } setupCharClick(dialpad_3_holder, '3')
dialpad_3_holder.setOnClickListener { dialpadPressed('3', it) } setupCharClick(dialpad_4_holder, '4')
dialpad_4_holder.setOnClickListener { dialpadPressed('4', it) } setupCharClick(dialpad_5_holder, '5')
dialpad_5_holder.setOnClickListener { dialpadPressed('5', it) } setupCharClick(dialpad_6_holder, '6')
dialpad_6_holder.setOnClickListener { dialpadPressed('6', it) } setupCharClick(dialpad_7_holder, '7')
dialpad_7_holder.setOnClickListener { dialpadPressed('7', it) } setupCharClick(dialpad_8_holder, '8')
dialpad_8_holder.setOnClickListener { dialpadPressed('8', it) } setupCharClick(dialpad_9_holder, '9')
dialpad_9_holder.setOnClickListener { dialpadPressed('9', it) } setupCharClick(dialpad_0_holder, '0')
setupCharClick(dialpad_asterisk_holder, '*', longClickable = false)
setupCharClick(dialpad_hashtag_holder, '#', longClickable = false)
dialpad_1_holder.setOnLongClickListener { speedDial(1); true }
dialpad_2_holder.setOnLongClickListener { speedDial(2); true }
dialpad_3_holder.setOnLongClickListener { speedDial(3); true }
dialpad_4_holder.setOnLongClickListener { speedDial(4); true }
dialpad_5_holder.setOnLongClickListener { speedDial(5); true }
dialpad_6_holder.setOnLongClickListener { speedDial(6); true }
dialpad_7_holder.setOnLongClickListener { speedDial(7); true }
dialpad_8_holder.setOnLongClickListener { speedDial(8); true }
dialpad_9_holder.setOnLongClickListener { speedDial(9); true }
dialpad_0_holder.setOnLongClickListener { dialpadPressed('+', null); true }
dialpad_asterisk_holder.setOnClickListener { dialpadPressed('*', it) }
dialpad_hashtag_holder.setOnClickListener { dialpadPressed('#', it) }
dialpad_clear_char.setOnClickListener { clearChar(it) } dialpad_clear_char.setOnClickListener { clearChar(it) }
dialpad_clear_char.setOnLongClickListener { clearInput(); true } dialpad_clear_char.setOnLongClickListener { clearInput(); true }
dialpad_call_button.setOnClickListener { initCall(dialpad_input.value, 0) } dialpad_call_button.setOnClickListener { initCall(dialpad_input.value, 0) }
@ -169,7 +166,6 @@ class DialpadActivity : SimpleActivity() {
private fun dialpadPressed(char: Char, view: View?) { private fun dialpadPressed(char: Char, view: View?) {
dialpad_input.addCharacter(char) dialpad_input.addCharacter(char)
maybePerformDialpadHapticFeedback(view) maybePerformDialpadHapticFeedback(view)
maybePlayDialpadTone(char)
} }
private fun clearChar(view: View) { private fun clearChar(view: View) {
@ -275,14 +271,15 @@ class DialpadActivity : SimpleActivity() {
} }
} }
private fun speedDial(id: Int) { private fun speedDial(id: Int): Boolean {
maybePlayDialpadTone(id.digitToChar()) if (dialpad_input.value.length == 1) {
if (dialpad_input.value.isEmpty()) {
val speedDial = speedDialValues.firstOrNull { it.id == id } val speedDial = speedDialValues.firstOrNull { it.id == id }
if (speedDial?.isValid() == true) { if (speedDial?.isValid() == true) {
initCall(speedDial.number, -1) initCall(speedDial.number, -1)
return true
} }
} }
return false
} }
private fun initRussianChars() { private fun initRussianChars() {
@ -296,13 +293,20 @@ class DialpadActivity : SimpleActivity() {
russianCharsMap['ь'] = 9; russianCharsMap['э'] = 9; russianCharsMap['ю'] = 9; russianCharsMap['я'] = 9 russianCharsMap['ь'] = 9; russianCharsMap['э'] = 9; russianCharsMap['ю'] = 9; russianCharsMap['я'] = 9
} }
private fun maybePlayDialpadTone(char: Char) { private fun startDialpadTone(char: Char) {
if (config.dialpadBeeps) { if (config.dialpadBeeps) {
if (char == '+') { pressedKeys.add(char)
// 0 is being long pressed toneGeneratorHelper?.startTone(char)
toneGeneratorHelper?.playTone('0') }
}
private fun stopDialpadTone(char: Char) {
if (config.dialpadBeeps) {
pressedKeys.remove(char)
if (pressedKeys.isEmpty()) {
toneGeneratorHelper?.stopTone()
} else { } else {
toneGeneratorHelper?.playTone(char) startDialpadTone(pressedKeys.last())
} }
} }
} }
@ -312,4 +316,43 @@ class DialpadActivity : SimpleActivity() {
view?.performHapticFeedback() view?.performHapticFeedback()
} }
} }
private fun performLongClick(view: View, char: Char) {
if (char == '0') {
clearChar(view)
dialpadPressed('+', view)
} else {
val result = speedDial(char.digitToInt())
if (result) {
stopDialpadTone(char)
}
}
}
@SuppressLint("ClickableViewAccessibility")
private fun setupCharClick(view: View, char: Char, longClickable: Boolean = true) {
view.isClickable = true
view.isLongClickable = true
view.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
dialpadPressed(char, view)
startDialpadTone(char)
if (longClickable) {
longPressHandler.removeCallbacksAndMessages(null)
longPressHandler.postDelayed({
performLongClick(view, char)
}, longPressTimeout)
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
stopDialpadTone(char)
if (longClickable) {
longPressHandler.removeCallbacksAndMessages(null)
}
}
}
false
}
}
} }

View File

@ -13,15 +13,18 @@ class ToneGeneratorHelper(context: Context) {
return audioManager.ringerMode in arrayOf(AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE) return audioManager.ringerMode in arrayOf(AudioManager.RINGER_MODE_SILENT, AudioManager.RINGER_MODE_VIBRATE)
} }
fun playTone(char: Char) = playTone(charToTone[char] ?: -1) fun startTone(char: Char) {
startTone(charToTone[char] ?: -1)
}
fun playTone(tone: Int, durationMs: Int = DIALPAD_TONE_LENGTH_MS.toInt()) { private fun startTone(tone: Int) {
if (tone != -1 && !isSilent()) { if (tone != -1 && !isSilent()) {
toneGenerator.stopTone() toneGenerator.startTone(tone)
toneGenerator.startTone(tone, durationMs)
} }
} }
fun stopTone() = toneGenerator.stopTone()
companion object { companion object {
const val TONE_RELATIVE_VOLUME = 80 // The DTMF tone volume relative to other sounds in the stream const val TONE_RELATIVE_VOLUME = 80 // The DTMF tone volume relative to other sounds in the stream
const val DIAL_TONE_STREAM_TYPE = STREAM_DTMF const val DIAL_TONE_STREAM_TYPE = STREAM_DTMF