Compare commits
2 Commits
c89d4f0204
...
cbaa339c37
Author | SHA1 | Date | |
---|---|---|---|
cbaa339c37 | |||
d1bf1c44a1 |
@ -5,6 +5,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"
|
<uses-permission android:name="android.permission.WRITE_SETTINGS"
|
||||||
tools:ignore="ProtectedPermissions" />
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.mezimmah.wkt9
|
package net.mezimmah.wkt9
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.inputmethodservice.InputMethodService
|
import android.inputmethodservice.InputMethodService
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
@ -17,6 +18,8 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import android.view.textservice.SentenceSuggestionsInfo
|
import android.view.textservice.SentenceSuggestionsInfo
|
||||||
import android.view.textservice.SpellCheckerSession
|
import android.view.textservice.SpellCheckerSession
|
||||||
import android.view.textservice.SuggestionsInfo
|
import android.view.textservice.SuggestionsInfo
|
||||||
|
import android.view.textservice.TextInfo
|
||||||
|
import android.view.textservice.TextServicesManager
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -47,11 +50,6 @@ import okio.IOException
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
//val info = arrayOf(TextInfo("banan#", 0, 6, 0, 0))
|
|
||||||
//
|
|
||||||
//spellCheckerSession?.getSentenceSuggestions(info, 10)
|
|
||||||
|
|
||||||
class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListener {
|
class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListener {
|
||||||
private val tag = "WKT9"
|
private val tag = "WKT9"
|
||||||
|
|
||||||
@ -210,10 +208,8 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
val inputClass = inputType?.and(InputType.TYPE_MASK_CLASS) ?: 0
|
val inputClass = inputType?.and(InputType.TYPE_MASK_CLASS) ?: 0
|
||||||
val typeVariation = inputType?.and(InputType.TYPE_MASK_VARIATION) ?: 0
|
val typeVariation = inputType?.and(InputType.TYPE_MASK_VARIATION) ?: 0
|
||||||
val typeFlags = inputType?.and(InputType.TYPE_MASK_FLAGS) ?: 0
|
val typeFlags = inputType?.and(InputType.TYPE_MASK_FLAGS) ?: 0
|
||||||
// val textServiceManager = getSystemService(TEXT_SERVICES_MANAGER_SERVICE) as TextServicesManager
|
|
||||||
|
|
||||||
cursorPosition = attribute?.initialSelEnd ?: 0
|
cursorPosition = attribute?.initialSelEnd ?: 0
|
||||||
// spellCheckerSession = textServiceManager.newSpellCheckerSession(null, locale, this, false)
|
|
||||||
|
|
||||||
val forceNumeric = resources.getStringArray(R.array.input_mode_numeric)
|
val forceNumeric = resources.getStringArray(R.array.input_mode_numeric)
|
||||||
|
|
||||||
@ -259,14 +255,18 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onGetSentenceSuggestions(suggestionsInfo: Array<out SentenceSuggestionsInfo>?) {
|
override fun onGetSentenceSuggestions(suggestionsInfo: Array<out SentenceSuggestionsInfo>?) {
|
||||||
|
clearCandidates()
|
||||||
|
|
||||||
suggestionsInfo?.map {
|
suggestionsInfo?.map {
|
||||||
val suggestions = it.getSuggestionsInfoAt(0)
|
val suggestions = it.getSuggestionsInfoAt(0)
|
||||||
|
|
||||||
for (index in 0 until suggestions.suggestionsCount) {
|
for (index in 0 until suggestions.suggestionsCount) {
|
||||||
val suggestion = suggestions.getSuggestionAt(index)
|
val suggestion = suggestions.getSuggestionAt(index)
|
||||||
|
|
||||||
Log.d(tag, "Suggestion: $suggestion")
|
candidates.add(suggestion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (candidates.isNotEmpty()) loadCandidates()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,28 +344,41 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
InputType.TYPE_TEXT_VARIATION_PERSON_NAME
|
InputType.TYPE_TEXT_VARIATION_PERSON_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
if (letterVariations.contains(variation)) {
|
val mode: WKT9InputMode = if (letterVariations.contains(variation)) {
|
||||||
allowSuggestions = false
|
allowSuggestions = false
|
||||||
|
|
||||||
enableInputMode(WKT9InputMode.ALPHA)
|
WKT9InputMode.ALPHA
|
||||||
} else if (lastInputMode == WKT9InputMode.ALPHA) {
|
} else if (lastInputMode == WKT9InputMode.ALPHA) {
|
||||||
allowSuggestions = flags != InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
allowSuggestions = flags != InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
||||||
|
|
||||||
enableInputMode(WKT9InputMode.ALPHA)
|
WKT9InputMode.ALPHA
|
||||||
} else enableInputMode(WKT9InputMode.WORD)
|
} else {
|
||||||
|
allowSuggestions = flags != InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
||||||
|
|
||||||
|
WKT9InputMode.WORD
|
||||||
|
}
|
||||||
|
|
||||||
|
spellCheckerSession = if (allowSuggestions) {
|
||||||
|
val textServiceManager = getSystemService(TEXT_SERVICES_MANAGER_SERVICE) as TextServicesManager
|
||||||
|
|
||||||
|
textServiceManager.newSpellCheckerSession(null, locale, this, false)
|
||||||
|
} else {
|
||||||
|
spellCheckerSession?.apply {
|
||||||
|
cancel()
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
enableInputMode(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun finishComposingText(): Boolean {
|
private fun finishComposingText(): Boolean {
|
||||||
return if (composing) {
|
return if (composing) {
|
||||||
composing = false
|
composing = false
|
||||||
|
|
||||||
lastComposedString?.let {
|
if (allowSuggestions && inputMode is AlphaInputMode) handleSuggestions()
|
||||||
commitHistory.add(it)
|
|
||||||
|
|
||||||
lastComposedString = null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (allowSuggestions) Log.d(tag, "History: $commitHistory")
|
|
||||||
|
|
||||||
updateInputStatus()
|
updateInputStatus()
|
||||||
|
|
||||||
@ -373,6 +386,28 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
} else false
|
} else false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleSuggestions() {
|
||||||
|
val lastComposed = lastComposedString ?: return
|
||||||
|
val lastChar = lastComposed.lowercase().last()
|
||||||
|
val code = keypad.codeForLetter(lastChar)
|
||||||
|
|
||||||
|
if (lastComposed.length != 1 || code == null) {
|
||||||
|
commitHistory.clear()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
commitHistory.add(lastComposed)
|
||||||
|
|
||||||
|
// loadSuggestions(commitHistory.joinToString(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadSuggestions(word: String) {
|
||||||
|
val info = arrayOf(TextInfo(word.plus("#"), 0, word.length + 1, 0, 0))
|
||||||
|
|
||||||
|
spellCheckerSession?.getSentenceSuggestions(info, 10)
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
private fun getIconResource(): Int {
|
private fun getIconResource(): Int {
|
||||||
val mode = inputMode?.mode ?: return resources.getIdentifier("wkt9", "drawable", packageName)
|
val mode = inputMode?.mode ?: return resources.getIdentifier("wkt9", "drawable", packageName)
|
||||||
@ -387,11 +422,20 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun goHome() {
|
private fun goHome() {
|
||||||
with(Intent(Intent.ACTION_MAIN)) {
|
if (Settings.canDrawOverlays(this)) {
|
||||||
this.addCategory(Intent.CATEGORY_HOME)
|
val startMain = Intent(Intent.ACTION_MAIN)
|
||||||
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
|
|
||||||
startActivity(this)
|
startMain.addCategory(Intent.CATEGORY_HOME)
|
||||||
|
startMain.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
||||||
|
startActivity(startMain)
|
||||||
|
} else {
|
||||||
|
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
||||||
|
|
||||||
|
intent.data = Uri.parse("package:$packageName")
|
||||||
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
||||||
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,11 +491,11 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadCandidates(highLight: Int? = null) {
|
private fun loadCandidates() {
|
||||||
val candidatesView = inputView?.findViewById<LinearLayout>(R.id.suggestions) ?: return
|
val candidatesView = inputView?.findViewById<LinearLayout>(R.id.suggestions) ?: return
|
||||||
|
|
||||||
candidates.forEachIndexed { index, candidate ->
|
candidates.forEachIndexed { index, candidate ->
|
||||||
val layout = if (index == highLight) R.layout.current_suggestion else R.layout.suggestion
|
val layout = if (index == candidateIndex) R.layout.current_suggestion else R.layout.suggestion
|
||||||
val candidateView = layoutInflater.inflate(layout, null)
|
val candidateView = layoutInflater.inflate(layout, null)
|
||||||
val textView = candidateView.findViewById<TextView>(R.id.suggestion_text)
|
val textView = candidateView.findViewById<TextView>(R.id.suggestion_text)
|
||||||
|
|
||||||
@ -486,7 +530,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
this.candidates.add(candidate)
|
this.candidates.add(candidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCandidates(candidateIndex)
|
loadCandidates()
|
||||||
composeText(this.candidates[candidateIndex])
|
composeText(this.candidates[candidateIndex])
|
||||||
handleComposeTimeout(timeout)
|
handleComposeTimeout(timeout)
|
||||||
}
|
}
|
||||||
@ -500,7 +544,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
|
|
||||||
if (!hasCandidates) return@launch
|
if (!hasCandidates) return@launch
|
||||||
|
|
||||||
loadCandidates(candidateIndex)
|
loadCandidates()
|
||||||
composeText(candidates[candidateIndex], 1)
|
composeText(candidates[candidateIndex], 1)
|
||||||
handleComposeTimeout(timeout)
|
handleComposeTimeout(timeout)
|
||||||
}
|
}
|
||||||
@ -582,7 +626,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
if (candidateIndex < 0) candidateIndex = candidates.count() - 1
|
if (candidateIndex < 0) candidateIndex = candidates.count() - 1
|
||||||
|
|
||||||
clearCandidateUI()
|
clearCandidateUI()
|
||||||
loadCandidates(candidateIndex)
|
loadCandidates()
|
||||||
composeText(candidates[candidateIndex])
|
composeText(candidates[candidateIndex])
|
||||||
handleComposeTimeout(this.timeout)
|
handleComposeTimeout(this.timeout)
|
||||||
}
|
}
|
||||||
@ -632,7 +676,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
if (candidateIndex >= candidates.count()) candidateIndex = 0
|
if (candidateIndex >= candidates.count()) candidateIndex = 0
|
||||||
|
|
||||||
clearCandidateUI()
|
clearCandidateUI()
|
||||||
loadCandidates(candidateIndex)
|
loadCandidates()
|
||||||
composeText(candidates[candidateIndex])
|
composeText(candidates[candidateIndex])
|
||||||
handleComposeTimeout(this.timeout)
|
handleComposeTimeout(this.timeout)
|
||||||
}
|
}
|
||||||
@ -701,7 +745,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
showStatusIcon(getIconResource())
|
showStatusIcon(getIconResource())
|
||||||
loadCandidates(candidateIndex)
|
loadCandidates()
|
||||||
composeText(candidates[candidateIndex])
|
composeText(candidates[candidateIndex])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ import net.mezimmah.wkt9.keypad.Key
|
|||||||
import net.mezimmah.wkt9.keypad.KeyEventResult
|
import net.mezimmah.wkt9.keypad.KeyEventResult
|
||||||
|
|
||||||
class AlphaInputMode: BaseInputMode() {
|
class AlphaInputMode: BaseInputMode() {
|
||||||
private val tag = "WKT9"
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mode = "alpha"
|
mode = "alpha"
|
||||||
status = Status.CAP
|
status = Status.CAP
|
||||||
|
@ -6,6 +6,8 @@ import net.mezimmah.wkt9.keypad.KeyEventResult
|
|||||||
import net.mezimmah.wkt9.keypad.KeyLayout
|
import net.mezimmah.wkt9.keypad.KeyLayout
|
||||||
|
|
||||||
open class BaseInputMode: InputMode {
|
open class BaseInputMode: InputMode {
|
||||||
|
protected val tag = "WKT9"
|
||||||
|
|
||||||
protected var newKey = true
|
protected var newKey = true
|
||||||
protected var keyIndex = 0
|
protected var keyIndex = 0
|
||||||
protected var lastKey: Key? = null
|
protected var lastKey: Key? = null
|
||||||
|
@ -7,7 +7,6 @@ import net.mezimmah.wkt9.keypad.KeyCommandResolver
|
|||||||
import net.mezimmah.wkt9.keypad.KeyEventResult
|
import net.mezimmah.wkt9.keypad.KeyEventResult
|
||||||
|
|
||||||
class FNInputMode: BaseInputMode() {
|
class FNInputMode: BaseInputMode() {
|
||||||
private val tag = "WKT9"
|
|
||||||
override val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
override val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
||||||
parent = super.keyCommandResolver,
|
parent = super.keyCommandResolver,
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@ import net.mezimmah.wkt9.keypad.Key
|
|||||||
import net.mezimmah.wkt9.keypad.KeyEventResult
|
import net.mezimmah.wkt9.keypad.KeyEventResult
|
||||||
|
|
||||||
class IdleInputMode : BaseInputMode() {
|
class IdleInputMode : BaseInputMode() {
|
||||||
private val tag = "WKT9"
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mode = "idle"
|
mode = "idle"
|
||||||
status = Status.NA
|
status = Status.NA
|
||||||
|
@ -7,7 +7,6 @@ import net.mezimmah.wkt9.keypad.KeyCommandResolver
|
|||||||
import net.mezimmah.wkt9.keypad.KeyEventResult
|
import net.mezimmah.wkt9.keypad.KeyEventResult
|
||||||
|
|
||||||
class NumericInputMode: BaseInputMode() {
|
class NumericInputMode: BaseInputMode() {
|
||||||
private val tag = "WKT9"
|
|
||||||
override val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
override val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
||||||
parent = super.keyCommandResolver,
|
parent = super.keyCommandResolver,
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import net.mezimmah.wkt9.keypad.KeyLayout
|
|||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
class WordInputMode: BaseInputMode() {
|
class WordInputMode: BaseInputMode() {
|
||||||
private val tag = "WKT9"
|
|
||||||
private val codeWord = StringBuilder()
|
private val codeWord = StringBuilder()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -16,7 +16,7 @@ object KeyLayout {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val en_US = mapOf(
|
val en_US = mapOf(
|
||||||
Key.N1 to listOf('.','?','!',',','-','\'','"','@','$','/','%',':','(',')'),
|
Key.N1 to listOf('.','?','!',',','-','+','=','\'','"','@','$','/','%',':','(',')'),
|
||||||
Key.N2 to listOf('a','b','c','ä','æ','å','à','á','â','ã','ç'),
|
Key.N2 to listOf('a','b','c','ä','æ','å','à','á','â','ã','ç'),
|
||||||
Key.N3 to listOf('d','e','f','è','é','ê','ë','đ'),
|
Key.N3 to listOf('d','e','f','è','é','ê','ë','đ'),
|
||||||
Key.N4 to listOf('g','h','i','ì','í','î','ï'),
|
Key.N4 to listOf('g','h','i','ì','í','î','ï'),
|
||||||
|
@ -44,7 +44,7 @@ class Keypad(
|
|||||||
return builder.toString()
|
return builder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun codeForLetter(letter: Char): Int? {
|
fun codeForLetter(letter: Char): Int? {
|
||||||
return letterCodeMap[letter]
|
return letterCodeMap[letter]
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application") version "8.1.0" apply false
|
id("com.android.application") version "8.1.1" apply false
|
||||||
id("org.jetbrains.kotlin.android") version "1.8.0" apply false
|
id("org.jetbrains.kotlin.android") version "1.8.0" apply false
|
||||||
id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false
|
id("com.google.devtools.ksp") version "1.8.10-1.0.9" apply false
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user