fix: Encapsulate Keyboard code

This commit is contained in:
J-Jamet
2023-07-29 18:59:16 +02:00
parent 07bbf232b6
commit a260e1d4e3
8 changed files with 97 additions and 71 deletions

View File

@@ -31,6 +31,7 @@ import com.kunzisoft.keepass.database.helper.SearchHelper
import com.kunzisoft.keepass.magikeyboard.MagikeyboardService import com.kunzisoft.keepass.magikeyboard.MagikeyboardService
import com.kunzisoft.keepass.model.SearchInfo import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.otp.OtpEntryFields import com.kunzisoft.keepass.otp.OtpEntryFields
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
import com.kunzisoft.keepass.utils.getParcelableCompat import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.WebDomain import com.kunzisoft.keepass.utils.WebDomain
@@ -116,7 +117,7 @@ class EntrySelectionLauncherActivity : DatabaseModeActivity() {
searchInfo: SearchInfo) { searchInfo: SearchInfo) {
// Setting to integrate Magikeyboard // Setting to integrate Magikeyboard
val searchShareForMagikeyboard = MagikeyboardService.activatedInSettings(this) val searchShareForMagikeyboard = isKeyboardActivatedInSettings()
// If database is open // If database is open
val readOnly = database?.isReadOnly != false val readOnly = database?.isReadOnly != false

View File

@@ -35,7 +35,6 @@ import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView import android.widget.ImageView
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
@@ -49,7 +48,6 @@ import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
@@ -97,6 +95,7 @@ import com.kunzisoft.keepass.settings.SettingsActivity
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION import com.kunzisoft.keepass.utils.BACK_PREVIOUS_KEYBOARD_ACTION
import com.kunzisoft.keepass.utils.KeyboardUtil.showKeyboard
import com.kunzisoft.keepass.utils.UriUtil.openUrl import com.kunzisoft.keepass.utils.UriUtil.openUrl
import com.kunzisoft.keepass.utils.getParcelableCompat import com.kunzisoft.keepass.utils.getParcelableCompat
import com.kunzisoft.keepass.utils.getParcelableExtraCompat import com.kunzisoft.keepass.utils.getParcelableExtraCompat
@@ -223,8 +222,7 @@ class GroupActivity : DatabaseLockActivity(),
&& PreferencesUtil.isKeyboardPreviousSearchEnable(this@GroupActivity)) { && PreferencesUtil.isKeyboardPreviousSearchEnable(this@GroupActivity)) {
// Change to the previous keyboard and show it // Change to the previous keyboard and show it
sendBroadcast(Intent(BACK_PREVIOUS_KEYBOARD_ACTION)) sendBroadcast(Intent(BACK_PREVIOUS_KEYBOARD_ACTION))
ContextCompat.getSystemService(this, InputMethodManager::class.java) view.showKeyboard()
?.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT)
} }
} }

View File

@@ -25,16 +25,17 @@ 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
import android.os.Build import android.view.Gravity
import android.util.Log import android.view.HapticFeedbackConstants
import android.view.* import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import android.widget.PopupWindow import android.widget.PopupWindow
import android.widget.TextView import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat import androidx.core.graphics.BlendModeCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@@ -53,8 +54,14 @@ import com.kunzisoft.keepass.model.SearchInfo
import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD
import com.kunzisoft.keepass.services.KeyboardEntryNotificationService import com.kunzisoft.keepass.services.KeyboardEntryNotificationService
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.* import com.kunzisoft.keepass.utils.KeyboardUtil.showKeyboardPicker
import java.util.* import com.kunzisoft.keepass.utils.KeyboardUtil.switchToPreviousKeyboard
import com.kunzisoft.keepass.utils.LOCK_ACTION
import com.kunzisoft.keepass.utils.LockReceiver
import com.kunzisoft.keepass.utils.REMOVE_ENTRY_MAGIKEYBOARD_ACTION
import com.kunzisoft.keepass.utils.registerLockReceiver
import com.kunzisoft.keepass.utils.unregisterLockReceiver
import java.util.UUID
class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionListener { class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionListener {
@@ -239,24 +246,6 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
} }
} }
private fun switchToPreviousKeyboard() {
var imeManager: InputMethodManager? = null
try {
imeManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switchToPreviousInputMethod()
} else {
@Suppress("DEPRECATION")
window.window?.let { window ->
imeManager?.switchToLastInputMethod(window.attributes.token)
}
}
} catch (e: Exception) {
Log.e(TAG, "Unable to switch to the previous IME", e)
imeManager?.showInputMethodPicker()
}
}
override fun onKey(primaryCode: Int, keyCodes: IntArray) { override fun onKey(primaryCode: Int, keyCodes: IntArray) {
val inputConnection = currentInputConnection val inputConnection = currentInputConnection
@@ -267,11 +256,11 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
playClick(primaryCode) playClick(primaryCode)
when (primaryCode) { when (primaryCode) {
KEY_BACK_KEYBOARD -> switchToPreviousKeyboard() KEY_BACK_KEYBOARD -> {
switchToPreviousKeyboard()
}
KEY_CHANGE_KEYBOARD -> { KEY_CHANGE_KEYBOARD -> {
ContextCompat.getSystemService(this, InputMethodManager::class.java) showKeyboardPicker()
?.showInputMethodPicker()
} }
KEY_ENTRY -> { KEY_ENTRY -> {
var searchInfo: SearchInfo? = null var searchInfo: SearchInfo? = null
@@ -471,14 +460,6 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry, toast) KeyboardEntryNotificationService.launchNotificationIfAllowed(context, entry, toast)
} }
fun activatedInSettings(context: Context): Boolean {
return ContextCompat.getSystemService(context, InputMethodManager::class.java)
?.enabledInputMethodList
?.any {
it.packageName == context.packageName
} ?: false
}
fun performSelection(items: List<EntryInfo>, fun performSelection(items: List<EntryInfo>,
actionPopulateKeyboard: (entryInfo: EntryInfo) -> Unit, actionPopulateKeyboard: (entryInfo: EntryInfo) -> Unit,
actionEntrySelection: (autoSearch: Boolean) -> Unit) { actionEntrySelection: (autoSearch: Boolean) -> Unit) {

View File

@@ -33,11 +33,11 @@ import com.kunzisoft.keepass.biometric.AdvancedUnlockManager
import com.kunzisoft.keepass.database.element.SortNodeEnum import com.kunzisoft.keepass.database.element.SortNodeEnum
import com.kunzisoft.keepass.database.search.SearchParameters import com.kunzisoft.keepass.database.search.SearchParameters
import com.kunzisoft.keepass.education.Education import com.kunzisoft.keepass.education.Education
import com.kunzisoft.keepass.magikeyboard.MagikeyboardService
import com.kunzisoft.keepass.password.PassphraseGenerator import com.kunzisoft.keepass.password.PassphraseGenerator
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.KeyboardUtil.isKeyboardActivatedInSettings
import com.kunzisoft.keepass.utils.UriUtil.isContributingUser import com.kunzisoft.keepass.utils.UriUtil.isContributingUser
import java.util.* import java.util.Properties
object PreferencesUtil { object PreferencesUtil {
@@ -631,7 +631,7 @@ object PreferencesUtil {
} }
fun isKeyboardSaveSearchInfoEnable(context: Context): Boolean { fun isKeyboardSaveSearchInfoEnable(context: Context): Boolean {
if (!MagikeyboardService.activatedInSettings(context)) if (!context.isKeyboardActivatedInSettings())
return false return false
val prefs = PreferenceManager.getDefaultSharedPreferences(context) val prefs = PreferenceManager.getDefaultSharedPreferences(context)
return prefs.getBoolean(context.getString(R.string.keyboard_save_search_info_key), return prefs.getBoolean(context.getString(R.string.keyboard_save_search_info_key),

View File

@@ -21,13 +21,11 @@ package com.kunzisoft.keepass.settings.preferencedialogfragment
import android.view.View import android.view.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.Button import android.widget.Button
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.EditText import android.widget.EditText
import android.widget.TextView import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceDialogFragmentCompat import androidx.preference.PreferenceDialogFragmentCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
@@ -157,20 +155,6 @@ abstract class InputPreferenceDialogFragmentCompat : PreferenceDialogFragmentCom
switchElementView?.visibility = View.GONE switchElementView?.visibility = View.GONE
} }
protected fun hideKeyboard(): Boolean {
context?.let {
ContextCompat.getSystemService(it, InputMethodManager::class.java)?.let { inputManager ->
activity?.currentFocus?.let { focus ->
val windowToken = focus.windowToken
if (windowToken != null) {
return inputManager.hideSoftInputFromWindow(windowToken, 0)
}
}
}
}
return false
}
fun setSwitchAction(onCheckedChange: ((isChecked: Boolean)-> Unit)?, defaultChecked: Boolean) { fun setSwitchAction(onCheckedChange: ((isChecked: Boolean)-> Unit)?, defaultChecked: Boolean) {
switchElementView?.visibility = if (onCheckedChange == null) View.GONE else View.VISIBLE switchElementView?.visibility = if (onCheckedChange == null) View.GONE else View.VISIBLE
switchElementView?.isChecked = defaultChecked switchElementView?.isChecked = defaultChecked

View File

@@ -0,0 +1,68 @@
package com.kunzisoft.keepass.utils
import android.app.Activity
import android.content.Context
import android.inputmethodservice.InputMethodService
import android.os.Build
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.core.content.ContextCompat
object KeyboardUtil {
fun Activity.hideKeyboard(): Boolean {
ContextCompat.getSystemService(this, InputMethodManager::class.java)?.let { inputManager ->
this.currentFocus?.let { focus ->
focus.windowToken?.let {windowToken ->
return inputManager.hideSoftInputFromWindow(
windowToken, 0)
}
}
}
return false
}
fun View.hideKeyboard(): Boolean {
return ContextCompat.getSystemService(context, InputMethodManager::class.java)
?.hideSoftInputFromWindow(windowToken, 0) ?: false
}
fun View.showKeyboard() {
ContextCompat.getSystemService(context, InputMethodManager::class.java)
?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}
fun InputMethodService.switchToPreviousKeyboard() {
var imeManager: InputMethodManager? = null
try {
imeManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
switchToPreviousInputMethod()
} else {
@Suppress("DEPRECATION")
window.window?.let { window ->
imeManager?.switchToLastInputMethod(window.attributes.token)
}
}
} catch (e: Exception) {
Log.e(TAG, "Unable to switch to the previous IME", e)
imeManager?.showInputMethodPicker()
}
}
fun Context.showKeyboardPicker() {
ContextCompat.getSystemService(this, InputMethodManager::class.java)
?.showInputMethodPicker()
}
fun Context.isKeyboardActivatedInSettings(): Boolean {
return ContextCompat.getSystemService(this, InputMethodManager::class.java)
?.enabledInputMethodList
?.any {
it.packageName == this.packageName
} ?: false
}
private const val TAG = "KeyboardUtil"
}

View File

@@ -29,19 +29,17 @@ import android.util.AttributeSet
import android.view.KeyEvent import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import android.widget.CompoundButton import android.widget.CompoundButton
import android.widget.EditText import android.widget.EditText
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
import com.kunzisoft.keepass.database.MainCredential import com.kunzisoft.keepass.database.MainCredential
import com.kunzisoft.keepass.hardware.HardwareKey import com.kunzisoft.keepass.hardware.HardwareKey
import com.kunzisoft.keepass.model.CredentialStorage import com.kunzisoft.keepass.model.CredentialStorage
import com.kunzisoft.keepass.utils.KeyboardUtil.showKeyboard
class MainCredentialView @JvmOverloads constructor(context: Context, class MainCredentialView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
@@ -231,8 +229,7 @@ class MainCredentialView @JvmOverloads constructor(context: Context,
fun focusPasswordFieldAndOpenKeyboard() { fun focusPasswordFieldAndOpenKeyboard() {
passwordTextView.postDelayed({ passwordTextView.postDelayed({
passwordTextView.requestFocusFromTouch() passwordTextView.requestFocusFromTouch()
ContextCompat.getSystemService(context, InputMethodManager::class.java) passwordTextView.showKeyboard()
?.showSoftInput(passwordTextView, InputMethodManager.SHOW_IMPLICIT)
}, 100) }, 100)
} }

View File

@@ -1,6 +1,5 @@
package com.kunzisoft.keepass.view package com.kunzisoft.keepass.view
import android.app.Activity
import android.content.Context import android.content.Context
import android.os.Build import android.os.Build
import android.os.Parcel import android.os.Parcel
@@ -11,11 +10,9 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.core.content.ContextCompat
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.DateInstant import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.Field import com.kunzisoft.keepass.database.element.Field
@@ -27,6 +24,7 @@ import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.otp.OtpElement import com.kunzisoft.keepass.otp.OtpElement
import com.kunzisoft.keepass.otp.OtpEntryFields import com.kunzisoft.keepass.otp.OtpEntryFields
import com.kunzisoft.keepass.settings.PreferencesUtil import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.KeyboardUtil.hideKeyboard
import com.kunzisoft.keepass.utils.readParcelableCompat import com.kunzisoft.keepass.utils.readParcelableCompat
@@ -102,8 +100,7 @@ abstract class TemplateAbstractView<
} }
buildTemplateAndPopulateInfo() buildTemplateAndPopulateInfo()
clearFocus() clearFocus()
ContextCompat.getSystemService(context, InputMethodManager::class.java) hideKeyboard()
?.hideSoftInputFromWindow(windowToken, 0)
} }
} }