稍微完善输入法以及输入法体验页
This commit is contained in:
@@ -5,28 +5,27 @@ import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import android.view.View
|
||||
import android.util.Log
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Button
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.example.myapplication.MyInputMethodService
|
||||
|
||||
|
||||
class ImeGuideActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var btnEnable: LinearLayout
|
||||
private lateinit var btnSelect: LinearLayout
|
||||
private lateinit var tvStep1Status: TextView//
|
||||
private lateinit var tvStep2Status: TextView//
|
||||
private lateinit var btnEnabledText: TextView//
|
||||
private lateinit var btnSelectText: TextView//
|
||||
private lateinit var btnEnabledimg: ImageView//
|
||||
private lateinit var btnSelectimg: ImageView//
|
||||
private val TAG = "ImeGuideActivity"
|
||||
|
||||
// 改成可空,避免 findViewById 返回 null 时直接 NPE
|
||||
private var btnEnable: LinearLayout? = null
|
||||
private var btnSelect: LinearLayout? = null
|
||||
private var tvStep1Status: TextView? = null
|
||||
private var tvStep2Status: TextView? = null
|
||||
private var btnEnabledText: TextView? = null
|
||||
private var btnSelectText: TextView? = null
|
||||
private var btnEnabledimg: ImageView? = null
|
||||
private var btnSelectimg: ImageView? = null
|
||||
|
||||
private var imeObserver: android.database.ContentObserver? = null
|
||||
|
||||
@@ -34,68 +33,79 @@ class ImeGuideActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_ime_guide)
|
||||
|
||||
// // 设置关闭按钮点击事件
|
||||
// findViewById<FrameLayout>(R.id.iv_close).setOnClickListener {
|
||||
// finish()
|
||||
// }
|
||||
Log.d(TAG, "onCreate")
|
||||
|
||||
btnEnable = findViewById(R.id.enabled)//btn启用输入法
|
||||
btnSelect = findViewById(R.id.select)//btn选择输入法
|
||||
tvStep1Status = findViewById(R.id.Steps)//第一步的提示
|
||||
tvStep2Status = findViewById(R.id.stepTips)//第二步的提示
|
||||
btnEnabledText = findViewById(R.id.btnEnabledText)//启用输入法按钮文字
|
||||
btnSelectText = findViewById(R.id.btnSelectText)//选择输入法按钮文字
|
||||
btnEnabledimg = findViewById(R.id.btnEnabledimg)//启用输入法按钮图片
|
||||
btnSelectimg = findViewById(R.id.btnSelectimg)//选择输入法按钮图片
|
||||
|
||||
// // 第一步:启用输入法
|
||||
// btnEnable.setOnClickListener {
|
||||
// startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
|
||||
// }
|
||||
|
||||
|
||||
// // 第二步:切换输入法
|
||||
// btnSelect.setOnClickListener {
|
||||
// val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
// imm.showInputMethodPicker()
|
||||
// }
|
||||
btnEnable = findViewById(R.id.enabled) // btn启用输入法
|
||||
btnSelect = findViewById(R.id.select) // btn选择输入法
|
||||
tvStep1Status = findViewById(R.id.Steps) // 第一步的提示
|
||||
tvStep2Status = findViewById(R.id.stepTips) // 第二步的提示
|
||||
btnEnabledText = findViewById(R.id.btnEnabledText) // 启用输入法按钮文字
|
||||
btnSelectText = findViewById(R.id.btnSelectText) // 选择输入法按钮文字
|
||||
btnEnabledimg = findViewById(R.id.btnEnabledimg) // 启用输入法按钮图片
|
||||
btnSelectimg = findViewById(R.id.btnSelectimg) // 选择输入法按钮图片
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
refreshStatus()
|
||||
registerImeObserver()
|
||||
try {
|
||||
refreshStatus()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "refreshStatus 崩了", e)
|
||||
}
|
||||
|
||||
try {
|
||||
registerImeObserver()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "registerImeObserver 崩了", e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
unregisterImeObserver()
|
||||
try {
|
||||
unregisterImeObserver()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "unregisterImeObserver 崩了", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerImeObserver() {
|
||||
if (imeObserver != null) return
|
||||
|
||||
|
||||
imeObserver = object : android.database.ContentObserver(
|
||||
android.os.Handler(android.os.Looper.getMainLooper())
|
||||
) {
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
super.onChange(selfChange)
|
||||
refreshStatus()
|
||||
try {
|
||||
refreshStatus()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "onChange -> refreshStatus 崩了", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentResolver.registerContentObserver(
|
||||
android.provider.Settings.Secure.getUriFor(
|
||||
android.provider.Settings.Secure.DEFAULT_INPUT_METHOD
|
||||
),
|
||||
false,
|
||||
imeObserver!!
|
||||
)
|
||||
|
||||
try {
|
||||
contentResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.DEFAULT_INPUT_METHOD),
|
||||
false,
|
||||
imeObserver!!
|
||||
)
|
||||
} catch (e: SecurityException) {
|
||||
// 部分 ROM/系统可能在这里抛异常
|
||||
Log.e(TAG, "registerContentObserver SecurityException", e)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "registerContentObserver 其他异常", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun unregisterImeObserver() {
|
||||
imeObserver?.let {
|
||||
contentResolver.unregisterContentObserver(it)
|
||||
try {
|
||||
contentResolver.unregisterContentObserver(it)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "unregisterContentObserver 异常", e)
|
||||
}
|
||||
}
|
||||
imeObserver = null
|
||||
}
|
||||
@@ -104,100 +114,144 @@ class ImeGuideActivity : AppCompatActivity() {
|
||||
private fun refreshStatus() {
|
||||
val enabled = isImeEnabled()
|
||||
val selected = isImeSelected()
|
||||
|
||||
|
||||
// 把所有 view 拿成局部变量并判空,避免 NPE
|
||||
val enableLayout = btnEnable
|
||||
val selectLayout = btnSelect
|
||||
val step1 = tvStep1Status
|
||||
val step2 = tvStep2Status
|
||||
val enableText = btnEnabledText
|
||||
val selectText = btnSelectText
|
||||
val enableImg = btnEnabledimg
|
||||
val selectImg = btnSelectimg
|
||||
|
||||
if (enableLayout == null || selectLayout == null ||
|
||||
step1 == null || step2 == null ||
|
||||
enableText == null || selectText == null ||
|
||||
enableImg == null || selectImg == null
|
||||
) {
|
||||
Log.e(TAG, "有 View 为 null,检查 activity_ime_guide.xml 的 id 是否匹配")
|
||||
return
|
||||
}
|
||||
|
||||
// 根据状态设置按钮的点击行为
|
||||
if (enabled) {
|
||||
// 输入法已启用时,禁用启用按钮的点击事件
|
||||
btnEnable.setOnClickListener(null)
|
||||
enableLayout.setOnClickListener(null)
|
||||
} else {
|
||||
// 输入法未启用时,设置启用按钮的点击事件
|
||||
btnEnable.setOnClickListener {
|
||||
enableLayout.setOnClickListener {
|
||||
startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
// 输入法已切换时,禁用选择按钮的点击事件
|
||||
btnSelect.setOnClickListener(null)
|
||||
selectLayout.setOnClickListener(null)
|
||||
} else {
|
||||
// 输入法未切换时,设置选择按钮的点击事件
|
||||
btnSelect.setOnClickListener {
|
||||
selectLayout.setOnClickListener {
|
||||
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
imm.showInputMethodPicker()
|
||||
}
|
||||
}
|
||||
|
||||
if(!enabled &&!selected) {
|
||||
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
btnEnabledText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
tvStep1Status.text = "Step one"
|
||||
tvStep1Status.text = "Step one"
|
||||
tvStep2Status.text = "Check to enable key of love"
|
||||
}else if(!enabled && selected){
|
||||
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
btnEnabledText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
tvStep1Status.text = "Step one"
|
||||
tvStep2Status.text = "Check to enable key of love"
|
||||
}else if(enabled && !selected){
|
||||
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
btnEnabledText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
btnSelectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
tvStep1Status.text = "Step two"
|
||||
tvStep2Status.text = "Select key of love as your default input method"
|
||||
}else if(enabled && selected){
|
||||
btnEnable.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
btnSelect.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
btnEnabledimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
btnSelectimg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
btnEnabledText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
btnSelectText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
tvStep1Status.text = "Completed"
|
||||
tvStep2Status.text = "You have completed the relevant Settings"
|
||||
if (!enabled && !selected) {
|
||||
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
enableText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
selectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
step1.text = "Step one"
|
||||
step2.text = "Check to enable key of love"
|
||||
} else if (!enabled && selected) {
|
||||
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
enableText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
selectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
step1.text = "Step one"
|
||||
step2.text = "Check to enable key of love"
|
||||
} else if (enabled && !selected) {
|
||||
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_unfinished)
|
||||
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_unfinished_img)
|
||||
enableText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
selectText.setTextColor(Color.parseColor("#FFFFFF"))
|
||||
step1.text = "Step two"
|
||||
step2.text = "Select key of love as your default input method"
|
||||
} else if (enabled && selected) {
|
||||
enableLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
selectLayout.background = getDrawable(R.drawable.ime_guide_activity_btn_completed)
|
||||
enableImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
selectImg.setImageResource(R.drawable.ime_guide_activity_btn_completed_img)
|
||||
enableText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
selectText.setTextColor(Color.parseColor("#A1A1A1"))
|
||||
step1.text = "Completed"
|
||||
step2.text = "You have completed the relevant Settings"
|
||||
Toast.makeText(this, "The input method is all set!", Toast.LENGTH_SHORT).show()
|
||||
startActivity(Intent(this, GuideActivity::class.java))
|
||||
try {
|
||||
startActivity(Intent(this, GuideActivity::class.java))
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "启动 GuideActivity 失败,检查是否在 Manifest 中声明", e)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否启用了本输入法 */
|
||||
private fun isImeEnabled(): Boolean {
|
||||
val enabledImes = Settings.Secure.getString(
|
||||
contentResolver,
|
||||
Settings.Secure.ENABLED_INPUT_METHODS
|
||||
) ?: return false
|
||||
|
||||
// 用真正的类,而不是手写字符串
|
||||
val myImeComponent = ComponentName(this, MyInputMethodService::class.java)
|
||||
// 系统存的是 flattenToString() 的格式
|
||||
val myImeId = myImeComponent.flattenToString()
|
||||
|
||||
// enabledImes 是一个用 ":" 分隔的列表
|
||||
return enabledImes.split(':').contains(myImeId)
|
||||
/** 是否启用了本输入法 */
|
||||
private fun isImeEnabled(): Boolean {
|
||||
return try {
|
||||
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
val myComponent = ComponentName(this, MyInputMethodService::class.java)
|
||||
|
||||
val result = imm.enabledInputMethodList.any { imeInfo ->
|
||||
imeInfo.packageName == myComponent.packageName &&
|
||||
imeInfo.serviceName == myComponent.className
|
||||
}
|
||||
|
||||
Log.d(TAG, "isImeEnabled = $result")
|
||||
result
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "isImeEnabled 出错", e)
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/** 是否已切换为当前输入法 */
|
||||
private fun isImeSelected(): Boolean {
|
||||
val currentIme = Settings.Secure.getString(
|
||||
/** 是否已切换为当前输入法 */
|
||||
private fun isImeSelected(): Boolean {
|
||||
return try {
|
||||
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||
val myComponent = ComponentName(this, MyInputMethodService::class.java)
|
||||
|
||||
val currentImeId = Settings.Secure.getString(
|
||||
contentResolver,
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD
|
||||
) ?: return false
|
||||
|
||||
val myImeComponent = ComponentName(this, MyInputMethodService::class.java)
|
||||
val myImeId = myImeComponent.flattenToString()
|
||||
|
||||
// 直接用同一种格式比对
|
||||
return currentIme == myImeId
|
||||
|
||||
Log.d(TAG, "DEFAULT_INPUT_METHOD = $currentImeId")
|
||||
|
||||
// 找到“当前默认 IME”对应的 InputMethodInfo
|
||||
val currentImeInfo = imm.enabledInputMethodList.firstOrNull { imeInfo ->
|
||||
imeInfo.id == currentImeId
|
||||
}
|
||||
|
||||
if (currentImeInfo == null) {
|
||||
Log.d(TAG, "currentImeInfo == null")
|
||||
return false
|
||||
}
|
||||
|
||||
val isMine = currentImeInfo.packageName == myComponent.packageName &&
|
||||
currentImeInfo.serviceName == myComponent.className
|
||||
|
||||
Log.d(TAG, "isImeSelected = $isMine")
|
||||
isMine
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "isImeSelected 出错", e)
|
||||
false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user